在实际运用的过程中,我们经常遇到一些场景需要测试我们接口的并发能力。
案例:
1.一个抽奖接口,在奖品被抽完后总不能还继续中到此奖品吧,万一是iphone等大奖,那就悲剧需要写邮件反省了。
2.一个下订单接口,用户要是操作速度或者网速的原因导致两个请求同时到达服务器,难道就插入两条订单么?同样,说不定还得邮件反省。
事由:
1.集群分布式部署导致synchronized在接口中控制并发失效
2.redis分布式锁不稳定,而且锁时间限制不容易具体定值
解决办法:
1.结合spring自带事务特性与数据库的行级锁,悲观锁 for update,就是在查询某条记录的时候限制其他线程对其进行修改,知道本线程提交事务,此方法当然较为影响程序接口的性能,希望有更好办法的大神指导评论!
结论:
多线程并发在我们编码过程中是很重要的,如何做好并发防守也是一个程序员应该需要有的素养和技能。
怎么进行并发测试呢?junit不支持多线程并发测试呢?有什么其他工具么?有的这边就指出一个应付并发测试的工具类
1.导入依赖包
<dependency>
<groupId>net.sourceforge.groboutils</groupId>
<artifactId>GroboTestingJUnit</artifactId>
<version>1.2.1</version>
</dependency>
2.怎么在测试类中使用呢?
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring-conf/spring-*.xml"})
public class CashBackTest {
//注入你要测试的业务类
@Autowired
private TestService testService;
@Test
@Transactional
public void initTest(){
//Runner数组,想当于并发多少个。
TestRunnable[] trs = new TestRunnable[20];
for (int i = 0; i < 20; i++) {
trs[i] = new MyHomeThread();
}
// 用于执行多线程测试用例的Runner,将前面定义的单个Runner组成的数组传入
MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);
// 开发并发执行数组里定义的内容
try {
mttr.runTestRunnables();
} catch (Throwable e) {
e.printStackTrace();
}
}
private class MyHomeThread extends TestRunnable {
@Override
public void runTest() throws Throwable {
//编写调用你要测试的接口方法,执行一个调用
testService.testMethold(params);
}
}
}
这个工具类是有点类似java的CountDownLatch似的,等到所有的线程都准备好才一起执行调用你要测试的方法,具体有兴趣的朋友可以去看一下这个工具类的源码,我这边就不多聊。有更好解决测试类测试并发接口的方法,欢迎广大猿友评论学习!