目标:需要单tomcat达到1000个线程,并发300 (轻松达到,可以达到2000并发,如果程序做写改动可以到1w并发单tomcat)
jmeter配置:最大线程数1000,集合点:300 ,持续10s ,也就是300个请求发送一次(对于服务端来说就是300个servlet线程)
接口单个请求处理平均时间:5ms
tomcat配置:nio , 最大连接数1000 ,最大线程数1000 ,最小线程数200 ,对我提供的端口是8180
redis:6379 、 6380两个端口, 和tomcat都部署在云服务器上,不存在网络问题
jvm配置:最大内存1G
程序内部逻辑:只是接收到数据每次请求和redis有3次交互,没有于数据库和其他io操作(除了日志,日志级别是ERROR)
服务器配置:
cpu:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 4
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 42
Stepping: 1
CPU MHz: 2394.454
BogoMIPS: 4788.90
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K
NUMA node0 CPU(s): 0-3
内存:M
free -m
total used free shared buffers cached
Mem: 7809 7388 421 0 357 3072
场景1:
程序部署在远程云服务器上,阿里云,压测的jmeter在公司内网(jmeter所在的机器可能会有性能问题,导致客户端处理请求超时等)
场景2:
程序部署在远程云服务器上,阿里云,压测的jmeter也部署在阿里云(排除网络因素和jmeter机器性能问题)
按照上述条件进行计算
1s=1000ms ;
每秒能处理200个(1000ms/5ms = 200个),这是最少的情况,因为5ms处理一次请求的话,处理一个请求就会释放一个线程,其他线程是可以进入的
300个请求的最大处理时间=300*5ms = 1500ms ,这是最大处理时间, 理论上在1秒以内可能是可以处理完成的
但是场景一压测结果很让人失望:
1000个线程,压倒800左右的时候,直接客户端就报错了,error百分比在3%左右,最小处理时间是3.5s,平均处理时间是5.5s , 最大处理时间是20s+
错误:{"code":500,"data":{"code":"ECONNRESET","path":null,"host":"balloon.qdingnet.com","port":443}} , 这个错误应该是客户端和服务的的Http链接发送断开了
查看服务器
cpu:30%最多
内存:10%最多 ,但是这里忘记看空闲内存了,不过通过云监控看是没有问题
io:也没有问题 top命令看到的 wa几乎没有
8180端口连接数:1000+ ,这就出现问题, 安装这个处理能力,不应该会出现这么多连接的,那么就怀疑是网络问题或者客户端jmeter的问题了, 在接收服务的返回的响应的时候,与服务端断开连接了,导致服务的的连接没有释放掉
服务的线程数监控:这个没有看,应该看看这个,连接数和线程数差距是不是很大,如果差距很大的话,那么就有问题了,就能基本确定是连接没有释放
场景一总结:
服务端的处理能力应该没问题,问题出现在jmeter接收响应能力不够(这应该主要是和网络有关系),导致服务的的连接没有释放掉,怀疑,后来证明不是这个问题
场景二的压测结果和场景一没有什么差别,那就和网络没关系了。
因为这个项目不是我负责,是别人负责,对项目的部署架构不了解,现在怀疑问题不是出自服务本身,而是在其他的地方,所以决定抛弃其他的一切东西,直接压接口
结果按照上述压测场景,直接压接口,顺利通过,具体数据如下
cpu:5%以下
内存:7%左右
8180最大连接数:170左右(这个就十分合理了,因为处理完一个请求就会释放链接)
tomcat线程数量:240左右(这个也比较合理)
磁盘io:几乎没有
最小响应时间:1ms
最大响应时间:1s
平均响应时间:100ms
那么单个服务器问题没问题,是什么导致之前的压测出现平均时间3s的情况呢?
了解了一下整个部署的情况
如上图所示:
首先查看nginx的机器情况,日志情况没有异常
然后查看mb服务的情况(双核,部署了8个mb实例),出现了瞬间cpu飙升的情况200% ,那么元凶找到了
解决办法:把mb服务分机器部署,再次压测,顺利通过
按照目前的api服务器的处理能力,tomcat等各种配置都不变化的情况下,达到单tomcat,2000并发不成问题,如果在多的话,就需要修改tomcat的连接数量,并优化程序,提高单次处理能力。如果想达到更高,可以设置数据缓存列表BlockingQueue,无限接收数据,异步多线程处理数据
本次压测查找问题的步骤如下:
1、看cpu,内存、磁盘io情况:通过top命令
2、看8180端口的连接数量:通过命令 netstat -nat|grep -i "8180"|wc -l ;netstat -na | grep 8180 | grep ESTABLISHED | wc -l 查看有效的连接,也就是打开的连接
3、看6379、6380连接数量:同2
4、看tomcat进程下的线程数量:通过命令 ps -mq pid | wc -l ;通过2、4 对比线程数和连接数,可以分析出是不是服务器处理时间导致连接没有释放还是客户端响应不够导致连接没有释放
5、tomcat nio , 可以实现无阻塞,一个线程可以处理多个请求