压测介绍 && 搭建压测平台
性能优化的终极目标:用户体验 = 产品设计(非技术) + 系统性能 ≈ 系统性能 = 快
应用性能调优是个大工程,包括指标、和影响因素。
指标可以从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)。其中
上图是对于三大指标的走势描述,可以总结为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)演示
-----------------------------------------------------------
---------------------------------------------
朦胧的夜 留笔~~