压测介绍 && 搭建压测平台

一、应用性能问题分析方法论

  性能优化的终极目标:用户体验 = 产品设计(非技术) + 系统性能 ≈ 系统性能 = 快

  应用性能调优是个大工程,包括指标、和影响因素。

    指标可以从web端(首屏时间、白屏时间、可交互时间、完全加载时间...)、移动端(端到端响应时间、Crash率、内存使用率、FPS(每秒刷新帧数))、后端(RT、TPS、并发数)来评判性能;对于后端的TPS和RT,影响因素:数据库读写、RPC、网络IO、逻辑计算复杂度、JVM(Throughput、Footprint、Latency)

     影响因素主要包括:

      产品设计:产品逻辑、功能交互、动态效果、页面元素

      基础网络:网络 = 连接介质(电缆、双绞线、光纤、微波、载波或通信卫星) + 计算终端(PC、手机、可穿戴设备、家具家电...)+ 基础网络设施:互联网,局域网(LAN)、城域网(MAN)、广域网(WAN)

      代码质量&架构:架构不合理、研发功底和经验不足、没有性能意识、数据库(慢查询、过多查询、索引使用不当、数据库服务器瓶颈… )

      移动端环境:设备类型&性能、系统版本、网络(WiFi、2G、3G、4G)

      硬件及云服务:服务器硬件,内存、磁盘、网卡…

二、压力测试简介

  压力测试说白了就是对系统不断施加压力,来预估系统负载能力的一种测试。一般而言,只有在系统基础功能测试验证完成、系统趋于稳定的情况下,才会进行压力测试。

  压测的目的:

    1、当负载逐渐增加时,观察系统各项性能指标的变化情况是否有异常

    2、发现系统的性能短板,进行针对性的性能优化

    3、判断系统在高并发情况下是否会报错,进程是否会挂掉

    4、测试在系统某个方面达到瓶颈时,粗略估计系统性能上限

  压测目标简单来说有4个:

    1、负载上升各项指标是否正常

    2、发现性能短板

    3、高并发下系统是否稳定

    4、预估系统最大负载 

  压测的五大指标:

    响应时间(RT)、吞吐量(Throughput,一般使用TPS或者QPS表示)、并发用户数、错误率(失败请求占比,在测试时,添加断言,不通过即为失败)、资源利用率(CPU、内存、使用率、系统负载、网络IO)。其中主要考虑RT、TPS、资源利用率

          

   上图是对于三大指标的走势描述,可以总结为2333,两个点,三条线,三个区,三个状态

    两个点:最优并发用户数(The Optimum Number of Concurrent Users)、最大并发用户数(The Maximum Number of Concurrent Users)

    三条曲线:吞吐量的曲线(紫色)、利用率(绿色)、响应时间曲线(深蓝色)

    三个区域:轻负载区(Light Load)、重负载区(Heavy Load)、塌陷区(Buckle Zone)

    三个状态描述:资源饱和(Resource Saturated)、吞吐下降(Throughput Falling)、用户受影响(End Users Effected)

  常用压测工具:

    1、Apache JMeter 可视化的测试工具

    2、LoadRunner 预测系统行为和性能的负载测试工具

    3、Apache的ab压力测试

    4、nGrinder 韩国研发一款性能测试工具

    5、PAS 阿里测试工具

三、使用Apache JMeter 可视化工具压测

  JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。 

(一)创建压测计划

  1、创建测试计划

        

  2、配置线程组

        

    线程数:20, 线程数量,这里设置了20个线程;ramp-up:表示在指定时间之内把这些线程全部启动起来。 如果n=1,那就表示要在1s以内把50个线程全部启动起来。循环次数:2000,表示把 20 thread 循环2000次,也就是说让每一个请求接口循环调用接口2000次。

    线程组配置解释

      线程数:用来发送http请求的线程的数量

        线程组常用来模拟一组用户访问系统资源(API接口)。假如客户机没有足够的能力来模拟较重的负载,可以使用JMeter的分布式测试功能,通过一个JMeter的Master来远程控制多个JMeter的Salve完成测试。

      循环次数:循环执行多少次操作

        循环次数表示了循环执行多少次操作!循环次数直接决定整个测试单个线程的执行时间,和整体测试执行时间。

        单线程执行时间 = 单请求平均响应时间 x 循环次数

        整个测试耗时 = 单线程执行时间 + (Ramp-Up - Ramp-Up / 线程数)

      Ramp-Up:建立全部线程耗时

        Ramp-Up Period (in-seconds) 代表隔多长时间执行,默认值是0,0代表同时并发。用于告知JMeter 要在多长时间内建立全部的线程。

   3、配置http请求

        

    选择Java,选择keepalive方式,使用长连接的方式,防止频繁的建立连接,关闭连接消耗性能。 

         

  4、配置断言

    JMeter断言常用有两种,一种是响应断言,一种是响应时间断言,如果响应内容不满足断言的配置,则认为这次的请求是失败的。

    响应断言:判断响应内容是否包含指定的字符信息,用于判断api接口返回内容是否正确。响应时间断言:判断响应时间,是否超过预期的时间,用于判断api接口返回时间是否超过预期。

    断言添加方式:右击测试计划的http请求,选择添加-->断言-->加响应断言和断言持续时间。配置响应断言:我们接口正常返回code值为20000,如果接口返回code值不是20000表示接口异常,为了测试,这里修改为接口返回code值不为20001则表示访问失败。 

        

    配置断言响应时间:设置请求接口时间超过10毫秒,则认为请求失败。

         

    验证断言配置:发起http请求,由于返回内容code值不为20000,以及访问时间超过10毫秒,所以认为访问失败。

  5、结果监听器

    配置监听器:监听压测结果【聚合报告和汇总结果很类似,看一个就行】

      聚合报告:查询结果信息聚合汇总,例如样本、平均值、通吐量、最大值、最小值...

      察看结果树:记录每一次压测请求

      图像结果:分析了所有请求的平均值、终止、偏离值和通吐量之间的关系。

      汇总结果:汇总压测结果

      汇总图:将压测结果以图像形式展示

(二)压测结果分析

  1、聚合报告

        

    样本(Sample):发送请求的总样本数量

    响应时间(RT):

      平均值(average):平均的响应时间

      中位数(median): 中位数的响应时间,50%请求的响应时间

      90%百分位(90% Line): 90%的请求的响应时间,意思就是说90%的请求是<=1765ms返回,另外10%的请求是大于等于1765ms返回的。

      95%百分位(95% Line): 95%的请求的响应时间,95%的请求都落在1920ms之内返回的

      99%百分位(99% Line): 99%的请求的响应时间

      最小值(min):请求返回的最小时间,其中一个用时最少的请求

      最大值(max):请求返回的最大时间,其中一个用时最大的请求 

    异常(Error):出现错误的百分比,错误率=错误的请求的数量/请求的总数

    吞吐量(Throughput):被测试接口的吞吐能力,每秒处理请求的数量

    Received KB/sec:每秒从服务器端接收到的数据量

    Sent KB/sec:每秒从客户端发送的请求的数量 

  2、查看结果树:记录了样本中每一次的请求

         

  3、汇总图与图形结果

    图形结果:分析了所有请求的平均值、终止、偏离值和通吐量之间的关系。横坐标:为请求数量,单位个数;纵坐标:响应时间,单位ms 

  4、汇总报告

        

    样本(sample): 发送请求的总样本数量

    响应时间【单位ms】:

      平均值(average):平均的响应时间

      最小值(min):请求返回的最小时间,其中一个用时最少的请求

      最大值(max):请求返回的最大时间,其中一个用时最大的请求

      标准偏差:度量响应时间分布的分散程度的标准,衡量响应时间值偏离平均响应时间的程度。

      标准偏差越小,偏离越少,反之亦然。

    异常(error): 出现错误的百分比,错误率=错误的请求的数量/请求的总数

    吞吐量TPS(throughout): 吞吐能力,这个才是我们需要的并发数

    每秒接收 KB/sec:每秒从服务器端接收到的数据量

    每秒发送KB/sec:每秒从客户端发送的请求的数量

(三)Jmeter插件(可视化指标)

  已有内容的分析维度不够,需要加入新的插件,例如TPS、QPS、RT【平均响应时间】、压力机活动线程数、服务器资源信息等

  1、开启插件

    下载地址:http://jmeter-plugins.org/downloads/all/,官网上下载plugins-manager.jar直接在线下载,下载后将jar包放在 Jmeter 的 lib/ext 目录下

        

    重启后,选择插件管理器,然后进行下载插件:

         

    一般会选择以下几个插件:

      PerfMon:监控服务器硬件,如CPU,内存,硬盘读写速度等

      Basic Graphs:主要显示平均响应时间,活动线程数,成功/失败交易数等

        Average Response Time 平均响应时间

        Active Threads 活动线程数

        Successful/Failed Transactions 成功/失败 事务数

      Additional Graphs:主要显示吞吐量,连接时间,每秒的点击数等

        

  2、配置插件

    如果可以配置如下三个监听器,就表示插件已经安装成功!执行压力测试,就可以看见压测的每秒事务数、响应时间,活动线程数等压测结果

      响应时间:jp@gc - Response Times Over Time

      活动线程数:jp@gc - Active Threads Over Time

      每秒事务数:jp@gc - Transactions per Second

  3、性能关键指标分析

    RT:响应时间

      平均值: 请求响应的平均时间是332ms

      中位数: 50%请求响应时间都在8ms之内

      P90: 90%的请求都在514ms之内响应结束

      P95: 95%的请求都在1051ms之内响应结束

      P99:99%的请求都在6979ms之内响应结束

      最小值: 请求响应最小时间2ms

      最大值: 请求响应的最大时间是35s

    压力机活动线程数:压力机活动线程数表明压测过程中施加的压力的情况

    TPS: 每秒的事务数,数字愈大,代表性能越好;

    QPS: 每秒的查询数量;数字愈大,代表性能越好;(1tps >= QPS)

    吞吐量: 每秒的请求数量,数字愈大,代表性能越好;

四、服务器硬件资源监控

  压测的时候,我们需要实时了解服务器【CPU、内存、网络、服务器Load】的状态如何,哪如何监控服务器的资源占用情况呢?方法有很多种:使用操作系统命令、使用finalshell、使用JMeter压测工具perfmon、使用Grafana+Prometheus+node_exporter

(一)使用操作系统命令监控

  操作系统命令监控:top、vmstat、iostat、iotop、dstat、sar...

  top命令:可以按 1 切换Cpu总览或者每一个cpu的具体情况;系统负载 load average 情况,1分钟平均负载,5分钟平均负载,15分钟平均负载。

  什么样的Load值得警惕?如下分析针对单核CPU:

   【0.0 - 0.7]】 :系统很闲,马路上没什么车,要考虑多部署一些服务

   【0.7 - 1.0 】:系统状态不错,马路可以轻松应对

   【等于1.0】 :系统马上要处理不多来了,赶紧找一下原因

   【大于5.0】 :马路已经非常繁忙了,进入马路的每辆汽车都要无法很快的运行

               

(二)使用JMeter压测工具perfmon

  服务器硬件资源的监控,必须在服务端安装serverAgent代理服务,jmeter才能实现监控服务端的cpu、内存、io的使用情况。ServerAgent下载地址:https://github.com/undera/perfmon-agent/blob/master/README.md

  服务启动默认4444端口,根本连接不上,因此自己创建一个部署脚本文件对此进行部署,且把端口修改为7879。启用7879端口后,服务器的cpu,io,内存使用情况就顺利的监控到了。

nohup java -jar ./CMDRunner.jar --tool PerfMonAgent --udp-port 7879 --tcp-port 7879 > log.log 2>&1 &

   然后在Jmeter中添加对于服务器的监控分析(监听器-jp@gc - PerfMon Metrics Collector)

  1、CPU

    填写IP和端口号,然后选择CPU,统计系统的和用户的指标

        

  2、内存

    填写IP和端口号,选择Memory,选择已使用和未使用的,单位选择Mb。

        

  3、网络IO

    填写IP和端口号,选择Network IO,选择发送和接收,单位选择Mb。

        

  4、磁盘IO   

    填写IP和端口号,选择Disk IO,选择已使用和未使用的,单位选择Mb。

        

五、压测监控平台

  准备四台机器,1台压力机,1台应用服务主机,1台数据库与缓存服务器,1CICD服务器:

    01:CICD服务器4C8G:Nginx、JMeter、CICD,内网ip:172.16.0.101(I/O优化)25Mbps峰值

    02:数据库与缓存服务器4C8G:MySQL、Redis、MQ、ES,内网ip:172.16.0.102(I/O优化)25Mbps峰值

    03:应用服务器01-4C8G:Application,内网ip:172.16.0.103(I/O优化)25Mbps峰值

    04:监控服务器02-4C8G:Grafana、Prometheus、InfluxDB,内网ip:172.16.0.104(I/O优化)25Mbps峰值

        

(一)收集Jmeter压测数据

  1、安装InfluxDB

  (1)下载InfluxDB的镜像

docker pull influxdb:1.8

  (2)启动InfluxDB的容器,并将端口 8083 和 8086 映射出来:

docker run -d --name influxdb -p 8086:8086 -p 8083:8083 influxdb:1.8

  (3)进入容器内部,创建名为jmeter的数据库:

# 进入 jmeter-influx 容器
docker exec -it influxdb /bin/bash
# 输入 influx 命令,即可进入 influx 操作界面
root@517f57017d99:/# influx
# 输入 create database jmeter 命令,创建名为 jmeter 的数据库
create database jmeter
# 输入 show databases 命令,查看数据库创建成功
show databases
# 输入 use jmeter 命令,应用刚才创建的数据库
use jmeter
# 输入 select * from jmeter 命令,查询库中有哪些数据
select * from jmeter

  2、配置后端监听器

    上面查询 InfluxDB 的 jmeter 数据库是没有数据的,想要将 JMeter的测试数据导入 InfluxDB ,就需要在 JMeter中使用 Backend Listener 配置 (添加-监听器-后端监听器),将数据同步到 InfluxDB。

         

    后端监听器实现一定要选择InfluxDB对应的实现。

    influxdbUrl:需要改为自己influxdb的部署ip和映射端口,我这里是部署在阿里云服务器,端口是容器启动时映射的8086端口,db后面跟的是刚才创建的数据库名称

    application:可根据需要自由定义,只是注意后面在 grafana 中选对即可

    measurement:表名,默认是 jmeter ,也可以自定义

    summaryOnly:选择true的话就只有总体的数据。false会记录总体数据,然后再将每个transaction都分别记录

    samplersRegex:样本正则表达式,将匹配的样本发送到数据库

    percentiles:响应时间的百分位P90、P95、P99

    testTitle:events表中的text字段的内容

    eventTags:任务标签,配合Grafana一起使用

  最后压测后,在influxDB中验证数据即可。

  3、 安装Grafana

    下载Grafana镜像

docker pull grafana/grafana

    启动Grafana容器:启动Grafana容器,将3000端口映射出来

docker run -d --name grafana -p 3000:3000 grafana/grafana

    验证部署成功:网页端访问http://ip:3000验证部署成功;默认账户密码:admin\admin

     添加数据源:选择DATA SOURCE,再选择Influxdb

        

     导入模:模板导入分别有以下3种方式:直接输入模板id号、直接上传模板json文件、直接输入模板json内容,在Grafana的官网找到我们需要的展示模板,Apache JMeter Dashboard,dashboad-ID:5496,JMeter Dashboard(3.2 and up),dashboad-ID:3351 

        

      选择对应的数据源    

         

    效果查看

        

(二)收集服务器指标

   1、安装node_exporter(在服务部署的机器上)

# 下载 
wget -c https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_ex porter-0.18.1.linux-amd64.tar.gz
# 解压 
tar zxvf node_exporter-0.18.1.linux-amd64.tar.gz
# 启动 
cd /opt/node_exporter-0.18.1.linux-amd64
nohup ./node_exporter > node.log 2>&1 &

   2、安装Prometheus(在监控平台机器上)

# 下载 
wget -c https://github.com/prometheus/prometheus/releases/download/v2.15.1/prometheus -2.15.1.linux-amd64.tar.gz
# 解压 
tar zxvf prometheus-2.15.1.linux-amd64.tar.gz

  修改配置文件

  - job_name: 'hero-Linux'
    static_configs:
    - targets: ['172.16.0.101:9100','172.16.0.102:9100','172.16.0.103:9100','172.16.0.104:9100']

   运行

# 运行
nohup ./prometheus > prometheus.log 2>&1 &

  访问验证:http://IP:9090/targets

        

  3、在Grafana中配置Prometheus的数据源  

  (1)在Grafana中配置Prometheus的数据源

  (2)Grafana导入Linux展示模板:导入Linux系统dashboard,Node Exporter for Prometheus Dashboard EN 20201010,dashboard-ID: 11074;Node Exporter Dashboard,dashboard-ID: 16098

    (3)演示

         

 

 

posted @ 2022-09-13 10:51  李聪龙  阅读(3707)  评论(0编辑  收藏  举报