使用Jmeter对接口进行压力测试

今天第一次使用Jmeter对系统进行了压力测试,测试了一下纯数据库方案以及添加了缓存的方案,结果惊人。

新建测试步骤

在测试计划中添加一个线程组

image.png

在新增的线程组中添加HTTP请求与查看结果树

image.png

image.png

在HTTP请求中添加聚合报告

image.png

容易踩坑的点:如果你的接口是POST请求,一定要多添加一个HTTP头管理器

image.png

在其中新增条目:Content-Type:Application/json

也就是以请求体以 json 的格式发送

image.png

如果接口需要登录,可以增加一个 cookie 管理器

完成这些之后,就可以将线程数设置为1,进行连接测试,连接正常后正式进入压力测试。

只使用MySQL处理请求

在设置并发量为每秒1000次的时候,可以看到MySQL的处理速度已经很慢了,平均响应时间达到了5235ms

image.png

image.png

使用Caffeine+Redis多级缓存方案

每秒1000次并发,对于缓存来说这么小的并发量只需略微出手,热身级别。平均响应时间2ms,相差2000+倍

image.png

image.png

继续增加并发数

2000并发测试:

image.png

3000并发测试:

image.png

4000并发测试:

image.png

5000并发测试:

image.png

6000并发测试:

image.png

可以看到,在6000并发时,虽然响应速度很快,但是异常值出现了波动,查看失败的请求,发现报错如下:

java
复制代码
java.net.ConnectException: Connection refused: connect at java.base/sun.nio.ch.Net.connect0(Native Method) at java.base/sun.nio.ch.Net.connect(Net.java:589) at java.base/sun.nio.ch.Net.connect(Net.java:578) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583) at java.base/java.net.Socket.connect(Socket.java:760) at java.base/java.net.Socket.connect(Socket.java:695) at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:531) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:636) at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:280) at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:386) at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:408) at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1310) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1243) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1129) at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1058) at org.apache.jmeter.protocol.http.sampler.HTTPJavaImpl.sample(HTTPJavaImpl.java:536) at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:66) at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1311) at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1300) at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:651) at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:570) at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501) at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268) at java.base/java.lang.Thread.run(Thread.java:1575)

这是由于服务端无法接受新连接导致的

java
复制代码
tomcat: # 接受和处理连接的最大线程数 threads: max: 2000 min-spare: 100 # 最大连接数,超出后进入等待队列 max-connections: 10000 # 等待队列长度,当所有线程忙碌、连接数达max-connections时,新请求在此队列等待 accept-count: 5000 # 连接超时时间(毫秒) connection-timeout: 5000

image.png

通过调整Tomcat服务器的配置,降低了异常值

但并发数是由客户端与服务器端共同制约的,使用 HTTPJavaImpl 的方式发送HTTP请求时,无法通过勾选 Use KeepAlive 来复用连接(Java 内置实现默认行为有限),这会导致每次请求都建立新的 TCP 连接,在高并发时客户端端口耗尽或服务端连接队列打满。

同时服务端操作系统:Linux 内核参数也需要调优,由于我是在本地windows测试,就跳过了这一步骤

每秒10000次并发

MySQL近乎宕机,平均响应时间达到24秒是一个灾难性的故障信号,意味着服务已基本不可用,并随时可能引发系统性崩溃。

image.png

引入了多级缓存的情况下,响应时间依旧很快,完全没有达到上限,但是异常值达到了44%

image.png

所以多级缓存只是构建高并发系统的一个必要条件,想要构建一个稳定的支持高并发的系统,还需要具备多种能力:分布式架构、限流降级熔断、容器与线程模型调优、JVM与GC调优、监控与快速定位等综合能力。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
北港
作者分享
有没有小伙伴接触过FDE(前沿部署工程师)这个岗位,工作内容跟平常的开发有什么区别呀? 听说跟驻场开发差不多🫠
2
以下面这份简历的状态冲刺秋招,目标薪资应该定到多少合适?背景双非本硕 由于时间原因暑假不打算找实习了,不过可以先投着,面试练手 近期打算把项目都部署上线,暑假再沉淀一下,学学消息队列
2
Day 87 ✅ 今天做了:①完成了力扣Hot100第九十三题:最长回文子串;②CSDN写了一篇博客:为什么HashMap的大小要设置为2的n次方;③使用Jmeter对接口进行了压测 ⏰ 明天计划:写一篇Jmeter压测接口的心得,MySQL裸奔和多级缓存的对比;算法刷题 📚 今日感悟:不能只会纸上谈兵,还是要切实提升自己的工程能力
2
Day 86 ✅ 今天做了:算法刷题:最小路径和;博客:Redis 常见数据结构;复习对话历史模块中的对话记忆实现;学完了工程项目生成需求分析和方案设计 ⏰ 明天计划:力扣刷题;写一篇关于Redis的博客;完成工程项目生成的后端开发 📚 今日感悟:AI真的是学无止境,只能尽可能提升深度与广度,容忍无知的存在
2
Day 85 ✅ 今天做了:刷了 1 道力扣算法题(不同路径),写了一篇 MySQL 分库分表的博客并自动加入了艾宾浩斯复习系统,复习了 4 个知识点(Redis 为什么快、Redis String 底层实现、冒泡排序算法、MySQL 分库分表),完成了代码生成项目的应用模块前端开发(Vue)。 ⏰ 明天计划:算法:最小路径和;博客:Redis 常见数据类型;项目:复习对话历史模块缓存实现 📚 今日感悟:为了准确记住冒泡排序的循环边界,我想了个办法:n个元素只需要走n-1趟,所以外层是n-1;每走一趟就有一个元素在最终位置,相当于数组长度-1,所以内层循环是n-1-i。这样即使忘记再推导也不会错了
3
下载 APP