Tomcat7压测(一)
目的
-
目的主要有几点:
- 了解空跑的TomcatQPS能达到多少
- 测试在Tomcat线程池,等待队列,最大连接数满了的情况下Tomcat的表现
- 通过压测暴露一些问题及对这些问题的解决
- 提升性能测试的姿势,算是一种锻炼吧
-
应该会分几个篇幅来分析,因为压测场景及数据比较多。
-
本篇主要是最基础的测试,后续会对压测中发现的问题做一些解决
压测
场景
Tomcat配置 | maxThreads="300"minSpareThreads="100"connectionTimeout="8000"enableLookups="false"acceptCount="100"acceptorThreadCount="1” | |
环境 | Docker容器内 | |
服务描述 | 当收到一个请求后,将处理该请求的线程sleep20ms,然后返回response。因为该服务本身几乎不占用任何系统资源,所以在CPU,Mem,IO上是不会产生瓶颈的(实际压测证实),且因为该场景下控制了每个请求的耗时,QPS不高,所以在网络IO上也不会产生瓶颈。因此会影响QPS的只有Tomcat线程池的参数和Tomcat的性能 | |
服务耗时 | 20ms |
数据(整理后)
序号 | API | TotalTime | Requests per second | Time per request | Tomcat线程池线程数 | 描述 |
---|---|---|---|---|---|---|
1 | ab -c100 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 107.443s | 4653.62 | 21.489ms | 201 | |
2 | ab -c150 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 72.462s | 6900.21 | 21.738ms | 293 | |
3 | ab -c200 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 54.558s | 9164.51 | 21.823ms | 273 | |
4 | ab -c300 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 50.134s | 9973.28 | 30.080ms | 300 | |
5 | ab -c350 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 44.010 s | 11361.12 | 30.807ms | 300 | |
6 | ab -c400 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 41.897s | 11934.02 | 33.518ms | 300 | |
7 | ab -c500 -n500000 -k http://172.16.200.18:8891/Jweb/1 | 40.968s | 12204.59 | 40.968ms | 300 | |
8 | ab -c100 -n500000 http://172.16.200.18:8891/Jweb/1 | 116.331s | 4298.09 | 23.266ms | 102 | |
9 | ab -c200 -n500000 http://172.16.200.18:8891/Jweb/1 | 59.024s | 8471.06 | 23.610ms | 201 | |
10 | ab -c250 -n500000 http://172.16.200.18:8891/Jweb/1 | 47.943s | 10429.08 | 23.971ms | 251 | |
11 | ab -c300 -n500000 http://172.16.200.18:8891/Jweb/1 | 45.464s | 10997.69 | 27.278ms | 300 | |
12 | ab -c400 -n500000 http://172.16.200.18:8891/Jweb/1 | 45.206s | 11060.57 | 36.164ms | 300 | |
13 | ab -c500 -n500000 http://172.16.200.18:8891/Jweb/1 | 42.562s | 11747.53 | 42.562ms | 300 |
总结
-
压测工具使用的是ApacheBench,-c表示并发数,-n表示请求数(即该次压测发起的请求总数),-k表示使用keep-alive。
-
观察前三组数据,可以发现当并发数小于Tomcat的maxThread时(Tomcat线程池没满时),QPS与并发数成正比(eg.第1、2组数据 6900/4653 ≈ 3/2 = 150/100 )。且每个请求的耗时约为21ms,其中20ms为服务sleep耗时,剩余的1ms为网络通讯和Tomcat处理耗时。客户端Ping服务端耗时约为0.3ms。所以Tomcat处理耗时应该$10^-1$ms级别。
-
观察第四组数据,由于并发数等于线程池最大对象,当新的请求进来时,需要等待线程释放,导致请求的耗时增加。
-
为什么前4组数据,Tomcat线程数都大于压测的并发数?
因为该压测场景下,Tomcat配置的是BIO模式。该模式下对于keep-alive的请求Tomcat线程会阻塞住并等待请求进来直到超时。通过观察多组数据下服务端TCP链接数,总结得出当带有keep-alive选项时,ApacheBench与服务端之间的建立的每个TCP链接只会处理100个请求(包括失败重试)(待验证是什么原因),当处理完100个请求后,ApacheBench会新建一个TCP链接继续压测,但之前的TCP链接并没有马上关闭。因此这些没有用且没有关闭的TCP连接会继续占用Tomcat线程。
-
观察不带keep-alive选项的数据,即8-13组数据。可以发现表现和1-8组数据差不多,但由于要建立更多的TCP连接,所以QPS会稍低一些。不过由于每个请求结束后会立即释放Tomcat线程,所以当并发数小于maxThread时,Tomcat线程数≈并发数。多出一两个线程是由于可能一个线程执行完后还没有释放,新的请求就进来了,所以会先创建一个新的线程来执行新的请求。
本文地址