摘要:公司的妹子不会做并发测试。并发测试是多个人同时访问一个服务,这不就是多线程吗于是灵光一现使用多线程来写并发测试代码。测试得出如下代码的执行效率最高,个并发耗时毫秒
公司的妹子不会做并发测试。做完一名程序猿看着有点干捉急。并发测试是多个人同时访问一个服务,这不就是多线程吗!于是灵光一现使用多线程来写并发测试代码。想想心理都有点小激动咧。效果比工具还好,废话不多说贴代码
添加Maven依赖
com.squareup.okhttp3 okhttp 3.8.1
com.squareup.okio okio 1.11.0
com.google.code.gson gson 2.8.0
先封装OKHTTP(使用CallBack思想做的封装),这个很早之前就封装了,公司移动端也是使用OKHTTP做的服务请求调用。经常遇到图片上传不了的问题,报的错是Socket连接超时的问题。解决这个问题so easy,把连接时间(KEEP_ALIVE)时间设置长一点就行了嘛!
OkHttp底层是用socket做的通信,现在很多应该的底层通信都用的Socket,例子不多说,全靠经验。
public abstract class HttpCommon {
/** * 设置连接超时时间为30000秒 */ private final static int CONNECT_TIMT_OUT = 30000; /** * 设置写超时时间为30000秒 */ private final static int WRITE_TIME_OUT = 30000; static { final OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder(); okHttpClient = httpBuilder.connectTimeout(CONNECT_TIMT_OUT, TimeUnit.SECONDS) .writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS).build(); } public abstract void callBack(String responseString); /** * get请求 * * @param url url地址 * @param map 请求参数 * @return 返回结果。如果为“”表示失败 */ public void get(String url, Map
}
public class RunThread {
private final String URL; private HttpCommon httpCommon; private int num; private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 1000000L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); private CountDownLatch countDownLatch; /** * @param url 服务URL地址, * @param num 并发访问次数,一般配置50+ */ public RunThread(String url, int num) { this.URL = url; this.num = num; this.countDownLatch = new CountDownLatch(num); httpCommon = new HttpCommon() { @Override public void callBack(String responseString) { System.out.println(responseString); } }; } public void testGet(Mapmap) { long startTime = System.currentTimeMillis(); for (int i = 0; i < num; i++) { executor.execute(new Runnable() { @Override public void run() { httpCommon.get(URL, map); countDownLatch.countDown(); } }); } try { countDownLatch.await(); long executeTime = System.currentTimeMillis() - startTime; System.out.println("一共消耗:" + executeTime +"毫秒"); } catch (InterruptedException e) { e.printStackTrace(); } } public void testPost(Map map, T t) { long startTime = System.currentTimeMillis(); for (int i = 0; i < num; i++) { executor.execute(new Runnable() { @Override public void run() { httpCommon.post(URL, map, t); countDownLatch.countDown(); } }); } try { countDownLatch.wait(); long executeTime = System.currentTimeMillis() - startTime; System.out.println("一共消耗:" + executeTime +"毫秒"); } catch (InterruptedException e) { e.printStackTrace(); } }
}
public static void main(String[] args) { String Url = "http://localhost:8085/test/add"; RunThread testMain = new RunThread(Url, 1000); // 测试Get请求 testMain.testGet(new HashMap<>());
// // 测试POST请求、PUT请求、DELETE请求
// testMain.testPost(new HashMap<>(), null);
}
上面是并发测试代码,那么如何写高并发测试代码呢!想到两点:一个锁、一个事务。先用Oracle做实验。
insert into testa (aaaa, bbbb) values (#{aaa}, #{aaa})
select max(aaaa) from testa
Service层代码,设置事务的隔离级别为不可重复读
Isolation.REPEATABLE_READ,结果报错“Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: 仅 READ_COMMITTED 和 SERIALIZABLE 是有效的事务处理级”。卧槽!还能不能一起愉快地玩耍了,Oracle居然只支持可重复读和可系列化两种事务级别,真是让人大跌眼镜。
贴一下高并发代码吧,经过实验,通过1000个并发请求,使用Durid + Lock成功1百个不到(在这里还是得喷一下阿里的技术),使用dbcp2 + Lock成功2百多个,使用dbcp2 + synchronized 竟然成功了940个。
@Autowired
private TestMapper testMapper;
//private Lock lock = new ReentrantLock();
@Transactional(isolation = Isolation.SERIALIZABLE)
public synchronized Integer test(Integer a, Integer b) {
int c = testMapper.select(); c += 1; testMapper.insert(c); return c;
}
代码有问题,找找错误原因吧。Spring AOP执行事务,会在Service方法执行之前就开始事务,再执行Synchronized同步方法。这样会导致查询数据并没有做同步,修改成如下代码,能完美解决问题。测试得出如下代码的执行效率最高,1000个并发耗时9018毫秒
@Autowired
private TestMapper testMapper;
//private Lock lock = new ReentrantLock();
public synchronized Integer test(Integer a, Integer b) {
int c = testMapper.select(); c += 1; update(c); return c;
}
@Transactional(isolation = Isolation.SERIALIZABLE)
public void update(int c) {
testMapper.insert(c);
}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71321.html
摘要:今天整理了一下近大半年以来的一些文章,和我的预期一样,很多文章我都忘记自己曾经写过了,这个记录的过程让我也有了新的理解。希望大家,收藏,点赞,加转发。 今天整理了一下近大半年以来的一些文章,和我的预期一样,很多文章我都忘记自己曾经写过了,这个记录的过程让我也有了新的理解。希望大家,收藏,点赞,加转发。 面试必备 面试必备:深入Spring MVC DispatchServlet 源码...
摘要:今天整理了一下近大半年以来的一些文章,和我的预期一样,很多文章我都忘记自己曾经写过了,这个记录的过程让我也有了新的理解。希望大家,收藏,点赞,加转发。 今天整理了一下近大半年以来的一些文章,和我的预期一样,很多文章我都忘记自己曾经写过了,这个记录的过程让我也有了新的理解。希望大家,收藏,点赞,加转发。 面试必备 面试必备:深入Spring MVC DispatchServlet 源码...
摘要:模式,单实例多进程,常用于多语言混编,比如等,不支持端口复用,需要自己做应用的端口分配和负载均衡的子进程业务代码。就是我们需要一个调度者,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整体性能最优,这就是负载均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:模式,单实例多进程,常用于多语言混编,比如等,不支持端口复用,需要自己做应用的端口分配和负载均衡的子进程业务代码。就是我们需要一个调度者,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整体性能最优,这就是负载均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
阅读 1369·2021-11-25 09:43
阅读 3582·2021-11-10 11:48
阅读 5090·2021-09-23 11:21
阅读 1597·2019-08-30 15:55
阅读 3507·2019-08-30 13:53
阅读 1234·2019-08-30 10:51
阅读 867·2019-08-29 14:20
阅读 1971·2019-08-29 13:11