最近公司做的项目,要求对相关接口做性能压力测试,在这里记录一下分析解决过程。

压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等。而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等查看CPU、内存使用情况,然后在排查IO问题,例如网络IO、磁盘IO的问题。 如果是磁盘IO问题,一般问题是SQL语法问题、MYSQL参数配置问题、服务器自身硬件瓶颈导致IOPS吞吐率问题。

 

  一、具体测试结果如下:

A接口、B接口性能壓力測試結果

測試接口

A接口、iB接口

測試工具

JMeter

測試機IP

172.xx.xx.xx,172.xx.xx.xx

软硬件環境

双臺Linux操作系統服務器
8核CPU
应用分配4GB內存
500GB硬盤

应用服务器:tomcat(集群)

数据库:mycat+mysql(读写分离)

測試人員

xxx

測試日期

2019/03/18-2019/03/19

測試方案

1.采用階梯式增壓模式,每個階梯壓10min,接口響應時間在3s內

2.并發線程數從30,50,100,200倍數往上增

3.每個事務處理響應時間為100ms

測試需求

1)系統可用性:99.5%;

2)A接口在3s內回應;

3)B接口在3s內回應;

4)服務器支撐業務容量達:40 TPS 以上;

5)服務器的內存、CPU使用率不超過 75%;

結果描述

從如下表格測試數據中可得出:
1.單接口場景下: A接口最優的TPS=76.4;90%Line的響應時間=782ms;當用戶數達 900個/秒以上時,有0.51%請求響應時間有超3s的,會影響用戶體驗;
2.單接口場景下: B接口最優的TPS=138.4;90%Line的響應時間=880ms; 當用户數達 1000個/秒以上時,有2.51%請求響應時間有超3s的,會影響用戶體驗;
3.混合接口場景下:A+B接口最優的TPS=90.7;90%Line的響應時間=656ms;當用户數達 1000個/秒以上時,有17.95%請求響應時間有超3s的,會影響用戶體驗;
 

注:如下結果數據表中,綠色標註為本次測試結果的最優值;  出錯率為響應時間超出3s的錯誤,測試中并未遇到出現程序上的異常問題.
【本輪測試結果】: PASS

場景

用例名稱

并發線程數(:個/秒)

發包總數(:請求數)

出錯率

平均TPS

平均響應時間(:ms)

90%Line(:ms)

被測試服務器CPU利用率

被測試服務器memory

單接口業務

A接口

300

45842

0.00%

76.4

389

782

18%

45%

A接口

500

46141

0.00%

76.8

645

1327

22%

50%

A接口

750

44129

0.00%

73.4

1012

2095

21%

50%

A接口

900

42871

0.51%

71.3

1250

2594

21%

58%

A接口

1000

41882

9.56%

69.7

1422

2993

30%

55%

單接口業務

B接口

500

83145

0.00%

138.4

358

880

30%

60%

B接口

700

56325

0.03%

93.8

739

1523

20%

50%

B接口

1000

57421

2.51%

95.5

1037

2502

15%

43%

混合接口業務

A+B接口

300

54442

0.00%

90.7

327

656

21%

56%

A+B接口

500

53068

0.00%

88.4

560

1218

25%

60%

A+B接口

700

49808

0.42%

82.9

836

1878

25%

55%

A+B接口

1000

93104

17.95%

61.9

959

3001

55%

50%

 

 

  二、初始应用配置调整:

    1、调整nginx的连接数为65535;

      events {
        use epoll;
        worker_connections 65535;
      }

线程数为300,默认为200;

ccept队列的长度为500,默认为100;

NIO模式

protocol="org.apache.coyote.http11.Http11NioProtocol"
        connectionTimeout="60000"
        maxThreads="300"
        acceptCount="500"
        URIEncoding="UTF-8"
        useBodyEncodingForURI="true"
        enableLookups="false"
        redirectPort="8443" />

 

    3、根据服务器内存情况,调整tomcat堆内存及垃圾回收器,这里分配4G(机器有8G),因为这台机器上部署了2个应用;

    4、在tomcat配置中(bin/catalina.sh),开启jmc远程监控端口

      JAVA_OPTS="-server -Dfile.encoding=UTF-8 -Xms4g -Xmx4g -Xmn2g -Xss512K -verbose:gc -XX:+UseConcMarkSweepGC
          -XX:MaxTenuringThreshold=10 -XX:PermSize=512m -XX:MaxPermSize=1g -XX:+ExplicitGCInvokesConcurrent -XX:GCTimeRatio=19
          -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=10
          -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=50
          -Xnoclassgc -XX:SoftRefLRUPolicyMSPerMB=0
          -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9433
          -Djava.rmi.server.hostname=172.xx.xx.xx 
          -Dcom.sun.management.jmxremote.ssl=false
          -Dcom.sun.management.jmxremote.authenticate=false"

 

  三、分析解决过程: 

    刚开始测试的时候,TPS上不去,只有30几:

springboot jmeter 压测报告 jmeter压测瓶颈_数据库

  然后进行以下分析:

  1、检查【应用cpu】使用情况,只有3%左右,cpu没用充分使用起来;

  2、检查【应用堆内存】使用情况,只使用了500M(实际分配了4G),内在也没有充分使用起来;

以上2项指标,可以通过jdk自带的jdk1.8.0_201/bin/jvisualVM工具查看:

springboot jmeter 压测报告 jmeter压测瓶颈_tomcat_02

springboot jmeter 压测报告 jmeter压测瓶颈_数据库_03

springboot jmeter 压测报告 jmeter压测瓶颈_tomcat_04

 

springboot jmeter 压测报告 jmeter压测瓶颈_数据库_05

springboot jmeter 压测报告 jmeter压测瓶颈_数据库_06

  

  3、查看慢sql,发现慢的SQL也没有,因为使用了Druid Monitor组件,可以使用它来分析

    http://172.xx.xx.xx:8089/xxx/druid/sql.html

springboot jmeter 压测报告 jmeter压测瓶颈_tomcat_07

 

  4、查看mycat日志是否已满,发现也没满。空间监控df -h ,防止文件系统空间满造成数据库hang住

    

springboot jmeter 压测报告 jmeter压测瓶颈_tomcat_08

  5、查看数据库磁盘io,发现比较低,只有10几%;

svctm<=6ms %util<80%

    

springboot jmeter 压测报告 jmeter压测瓶颈_数据库_09

  6、最后分析JMeter工具中的压测结果,发现有很多响应时间超过3s以上的,在应用日志中找到这些记录,分析调用链路(分布式系统)各个节点的耗时,发现有个应用中使用了synchronized锁,在高并发情况下获取锁耗时3s以上;

    

springboot jmeter 压测报告 jmeter压测瓶颈_Line_10

  7、修复程序,重新压测,tps就达到了80左右,耗时多的记录也基本上没有了,至此,此次性能压力测试已结束。

 

注意:重复压测,会发现随着压测的次数增多,TPS会越来越低。那是因为应用中的日志会越来越大,导致写入时hand住了,要删除日志文件。

 

  四、mysql性能监控指标: 

  在分析过程中,在网上查了不少资料,在这里也简单描述一下:

1、os层面
        空间监控df -h ,防止文件系统空间满造成数据库hang住
        性能cpu监控
            vmstat 
                r队列,这个队列需要小于cpu核数,最大不要超过4倍???
            top load average队列数量,同上???
            top中sys cpu占比小于5%,iowait占比小于5%,user占比小于70%
            top H线程占cpu占比,不要出现70%+的线程
2、内存
        vmstat中出现swap in out    ,free至少2G以上
3、io
        iostat -x 中  r/s     w/s 
        svctm<=6ms
        %util<80%
4、网络监控
        sar监控中,网络带宽不需要达到90%,一般1000Mbit/s 带宽足够使用,除了备份等场景

    5、数据库
        真实负载监控

   6、监控工具
      ZABBIX