背景
某客户施行DAP,在上线前须要对DAP进行压力测试,有专门的压力测试环境,并且要求并发可能达到1000,团队应用jmeter作为压测工具,整个零碎架构很简略浏览器->Nginx->Tomcat
,在压测的时候碰到以下问题
- 对DAP流程提交接口进行压测,压测不通过
- 部署一个仅仅返回申请参数,没有任何业务逻辑,压测不通过
- 绕过Nginx,间接对Tomcat进行压测,压测通过
- 间接对Nginx进行压测,压测Nginx welcome页面,压测不通过
并且对Nginx进行了大量的调优,能调的参数根本都试过,压测不通过,总结下来就是,只有通过Nginx,压测就不通过,看来问题呈现在Nginx上
环境信息
- Nginx:16CPU 64G内存
- Nginx配置,这里只列几个比拟重要的参数
worker_processes 16;worker_connections 1000;keepalive_timeout 60;
这些参数都调整过,对后果影响不大,当然如果调的太极其,比方worker_processes设置为1,必定是会报错的。
- Tomcat:16CPU 64G内存
这个配置Nginx跑1000并发齐全是足够的
排查
先看下两个测试后果比照
- 压测tomcat简略接口,并发1000,循环50次,总共50000次申请
压测后果
所有申请没有呈现Error
- 压测Nginx welcome页面,并发1000,循环50次,总共50000次申请
有百分之0.31%的错误率,尽管不高,但这个错误率是始终有的,而且如果说Nginx的压测不如Tomcat,置信这个后果大家都承受不了,Nginx是负载平衡产品中公认最强的产品,一个是负载平衡,一个是应用服务器,负载平衡最重要的就是并发能力,应用服务器最重要的是业务能力,如果Tomcat在并发能力上超过Nginx,可能会颠覆很多人的认知。所以这其中必定是有问题的。
Nginx压测申请的谬误次要集中在以下几点
- java.net.ConnectionException: Connection refused: connect
- java.net.SocketException: Connection reset
- java.net.SocketException: Unexpected end of file from server
- org.apache.http.NoHttpResponseException: failed to respond
基本上是网络谬误,为了排除网络谬误,做了两个测试
本地运行
我本人电脑(MAC)开nginx和tomcat,用jmeter进行压测,后果更不现实,也是1000并发
尽管有这么高的错误率,然而不论是nginx还是tomcat,并没有报错,这能阐明什么问题呢,阐明很可能是内核层面就报错了,也就是申请基本就没进来
Linux主机运行
Jmeter反对在LInux下运行,也反对命令行模式,因而能够思考在内网服务器找一台同网段主机作为压测机器,步骤如下
- 将jmeter安装包上传到Linux压测机并解压
- 在本地配好测试计划,保留为jmx文件,并将jmx文件上传至Linux压测机
- 执行以下命令以命令行模式开启压测
apache-jmeter-5.4.1/bin/jmeter.sh -n -t plan.jmx -l plan.jtl
- 将后果文件plan.jtl下载到本地,在汇总报告中点击Browser关上文件
错误率为0,联合本地运行的后果,能够猜想跟压测机的环境无关。
压测机
本次应用的压测机是一台windows 7主机,如果是压测机的起因,那么为什么压tomcat就没问题,压nginx就有问题,两次压测到底区别在哪,咱们能够用wireshark进行抓包,看两次压测在网络包上有什么不同
- Nginx压测抓包,发现有大量RST的包,并且继续疾速呈现
RST是连贯敞开时会发送的数据包
- Tomcat压测抓包也有RST的包,然而速度显著较慢,而且数量不多
也就是说,Nginx压测一直在创立连贯和敞开连贯,tomact创立连贯和敞开连贯动作并没有那么频繁,咱们能够在windows上用以下命令查看连贯状况
netstat -a | find /i /c "TIME_WAIT"
该命令能够统计以后零碎处于TIME_WAIT状态的连接数,TIME_WAIT示意连贯处于行将敞开的状态,这时候连贯所占用的端口仍然无奈开释,无奈进行再次调配,如果短时间内产生大量的TIME_WAIT连贯,容易导致端口号耗尽以至于无奈创立新的连贯,服务无奈响应
- Tomcat压测 TIME_WAIT连接数状况
TIME_WAIT
示意期待敞开的连接数,能够看到迟缓增长,并且达到两千左右进行增长
- Nginx压测TIME_WAIT连接数状况
能够看到快速增长,并且总数能够达到2w以上,最多能够达到4w,所以两次压测的区别就是TIME_WAIT的数量, 那为什么会产生这种后果,以下是我的集体猜想
nginx采纳的是epoll非阻塞模型,tomcat采纳的是线程模型,一个申请一个线程,属于阻塞模型,所以nginx能够段时间内"吃掉"大量的连贯,tomcat须要排队进入,这样就造成了以上景象,nginx短时间创立大量连贯,tomcat则是迟缓减少连贯
论断
windows作为压测机进行高并发压测并不适合,因为会在短时间内产生大量连贯,windows作为工作PC,在这方面解决能力不如Linux,加上网络稳定等因素,容易造成谬误,造成压测后果失真,尽管能够通过优化局部参数升高错误率,但解决不了基本问题,倡议通过同网段Linux主机作为压测机,测试计划能够在windows进行配置,后果剖析也能够在windows中实现,但执行测试工作倡议在Linux主机上进行。