0、准备
0.1 java
0.2 jmeter
0.3 文件传输工具
0.4 openssl
0.5 简易的服务器(启动和安装在仓库中有说明)
1、简介
jmter是一个接口测试工具常用于性能测试。相对于传统的LoadRunner,轻量和跨平台性都是其优点以至于更加流行(我本人其实也很喜欢lr,但是王权没有永恒),本章在于入门与介绍基础支持。文末会附上例子的开箱即用的链接。
2、录制
2.1、http代理配置
我们在测试计划下添加非测试元件->http代理服务器
我们需要设置好端口和url前缀,这里我设置了8888和https://www.baidu.com。然后我们要先添加线程组,然后在目标选择器选择对应的线程组,后面录制的内容会记录在线程组内。这里需要先启动生成证书即
ApacheJMeterTemporaryRootCA.crt
文件。出现下面的弹窗就成功生成了。有一个注意点就是,证书会有7天内有效。
代理知识
代理实际上指的就是代理服务器,英文叫作proxy server,它的功能是代理网络用户去取得网络信息。可以这么说代理是一个中间人,它帮你转发和接收消息。
即从 A <-> B 到 A < -> C < -> B
2.2、证书设置
证书在jmeter安装目录下bin目录,可以看到ApacheJMeterTemporaryRootCA.crt,然后我们用openssl将crt文件转pem文件。
类unix
# linux和mac 直接使用代码即可
cd $JMETER_PATH/bin
openssl x509 -in ApacheJMeterTemporaryRootCA.crt -out ApacheJMeterTemporaryRootCA.pem -outform PE
mv ApacheJMeterTemporaryRootCA.pem ~/Desktop
windows
我们找到自己jmeter的安装目录,再进入到bin,然后输入cmd
打开控制台输入
openssl x509 -in ApacheJMeterTemporaryRootCA.crt -out ApacheJMeterTemporaryRootCA.pem -outform PE
生成我们的文件。
然后我们发送文件到手机上安装证书即可,安装证书步骤就不赘述了,和我们抓包软件安装证书差不多。
2.3 代理设置(和抓包一样的,略)
2.4 抓包
以上的步骤只是为了jmeter代理我们的手机,来为我们抓包。我们按照我们的性能测试方案,去执行我们的行为路径。经过多次录制我们会得到多个行为路径。
3、开始性能测试
本章测试的服务器是我自己手撸,覆盖的场景没有活动的场景(如:浏览百亿补贴),仓库会附上3.2 优化后的.jmx
文件
3.0 线程组是怎样执行的
原文就不贴了,简而言之定时器在采样器前执行,如果了解更多可以下方链接查看
Timers¶
线程组执行顺序¶
3.1 定时器
3.1.0 被忽略的定时器们,能望文生义的定时器就忽略吧
3.1.1 高斯随机定时器
应该叫高斯分布的定时器或者说正态分布定时器。它符合标准正态分布,根据默认配置 100,300,请求前会等待(300+0~100)ms,根据正态分布规律,等待时间会集中在(300+50)ms。
我们可以通过平时埋点数据得出我们的标准查范围,制定合理的标准差。不过标准正态分布模型未必符合实际状态
3.1.2 泊松随机定时器
它符合泊松分布,根据默认配置 100,300,请求前大约会等待(300+100)ms,下面是我自己做的测试,样本太小参考性可能不大,这次测试大概在 380-420ms
3.1.3 统一随机分布定时器
和上面差不多的公式是一样的,但是分布是随机的而已。
3.1.4 恒定吞吐量定时器
如设置100,一分钟内只要超过100tps则会停止请求,等待下一分钟再开始请求,根据服务器吞吐量来控制暂停和开始,我们最好还是通过函数来动态的暂停和开始请求。
3.1.5 同步计时器
它有点类似于lr的集合点,它会阻塞指定数量的线程,然后一次性释放,为了可能的失败导致线程数量达不到指定数量而一直等待,我们需要设置过期时间,避免永久等待。p.s(在分布式执行时中请不要超过最小线程数)
3.1.6 精确吞吐量定时器(玩不转,期待大佬补充。后面还是尝试啃掉它)
3.1.7 BeanShell定时器(脚本类型定时器,beanshell是java的子集,按理而言可以玩出花来。此处不展开)
3.1.8 JSR223定时器(同上)
3.19 BSF定时器(同上)
3.2 优化(相比于优化我倾向于说是行为抽象,这里是针对单元测试的优化,3.3实战我们会再做调整,那将是本章的最终版本。)
我们将录制下来的线程将他变成一个个具体的用户,赋予他们各种随机行为。
3.2.1 随机csv选择器(Random CSV Data Set Config)
这个需要我们另外安装,安装好后我们这样配置,便配置好username,password两个变量。
3.2.2 登录接口配置
新版jmeter去除了__MD5这个函数,我们使用${__digest(MD5,变量,,,)}替代。
由于接口直接返回json,我们直接使用json提取器提取token(使用正则也是可以的)
3.2.3 下单接口
请求头设置,我们引用提取的token
good_ids随机生成(使用beanshell生成)
请求设置,这里需要注意引用变量需要加中括号
json提取器提取order_no供订单详情接口和支付接口使用
3.2.4 订单详情接口
请求头设置同下单接口
请求参数采用order_no
3.2.5 支付接口(同订单详情接口略)
3.2.6 商品列表(可以游客访问)
请求参数,我们只调整page,对于前端而言分页大小都是固定的,我们使用jmeter的随机数函数即可,商品总量是1000,范围为1-100即可。
我们匹配全部商品id,通过随机匹配次数,去提取一个任意的商品id(json提取器的语法学习)
3.2.7商品详情(可以游客访问)
请求参数配置
3.3 实战
3.3.1 测试指标(实际指标是协商制定的。)
我们开始规划一个大致的测试指标(参考阿里云)这里我按最低的算,毕竟比较菜。
RT:500 ms、TPS:500-10000、QPS:1500、VU: 5000、FR:99.4%。
3.3.2具体的业务场景及用户量比例
scene1 登录后挂机 vu占比:1
接口 :/jmeter/login
scene2 下单支付 vu占比:4
接口 :/jmeter/login
/jmeter/app/order/add
/jmeter/pay
/jmeter/app/order/detail
scene3 下单浏览 vu占比:2
接口 /jmeter/login
/jmeter/app/order/add
/jmeter/app/order/list
/jmeter/app/order/detail
scene4 浏览商品 vu占比:2
/jmeter/login
/jmeter/app/good/list
/jmeter/app/good/detail
scene5 闲逛的:vu占比:1
/jmeter/login
/jmeter/app/good/list
这里做的比较粗,我将用户文件划分到三份文件,使用tests/attribute.py
划分即可,具体的比例调整在脚本内修改即可。
具体的比例是:
1、登录后挂机用户:1
2、订单相关场景用户:6
3、浏览商品场景用户:3
- tps
系统内有三个接口的qps == tps,分别为
/jmeter/app/order/add
/jmeter/pay
/jmeter/app/order/detail
(这个接口在本次测试中不会产生tps,进阶篇会用上)
单线程 2 tps/sec,一个用户的下单浏览行为为 1tps/sec。,我们按照比例计算出下单支付
场景线程数为334
,下单浏览
场景并发数为166
,按vu占比得出各个场景的线程数
scene1 登录后挂机 83
scene2 下单支付 334
scene3 下单浏览 166
scene4 浏览商品 166
scene5 闲逛的:83 - qps
根据tps的用户数,我们得出qps = 83*1 + 334*4 + 166 * 4 + 166 * 3 +83 *2= 2747 > 1500
,由于高于标准,不调整线程数。 - vu 835(暂时不加,不知道服务器顶不顶的住,虽然没达到5000)
3.3.3 具体配置
-
随机csv选择器修改
修改文件为对应场景的文件名
p.s登录场景勾掉复用的数据的选项
-
同步定时器
模拟用户数为我们上面推算的线程数
时间我们默认为1秒
-
线程组设置
线程数同推算的线程数
循环为永远
持续时间为半个小时
启动延时因为我们有定时器,直接设置为0即可
3.3.4报告生成
我们可以使用tests/test_launch.py
来开始测试
python3 tests/test_launch.py debug #打开可视化界面
python3 tests/test_launch.py #直接运行
#对应效果
#report dir path is {path to report}
# Creating summariser
# Created the tree successfully using {path_to_jmx_file}.jmx
# Starting the test @ Sun Feb 21 15:39:48 CST 2021 (1613893188586)
# Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
# summary + 510 in 00:00:11 = 48.4/s Avg: 2365 Min: 82 Max: 6114 Err: 64 (12.55%) Active: 837 Started: 842 Finished: 5
# summary + 1771 in 00:00:30 = 58.6/s Avg: 7989 Min: 0 Max: 29329 Err: 628 (35.46%) Active: 529 Started: 842 Finished: 313
# summary = 2281 in 00:00:41 = 56.0/s Avg: 6732 Min: 0 Max: 29329 Err: 692 (30.34%)
# summary + 911 in 00:00:23 = 40.4/s Avg: 13530 Min: 29 Max: 29199 Err: 187 (20.53%) Active: 0 Started: 842 Finished: 842
# summary = 3192 in 00:01:03 = 50.4/s Avg: 8672 Min: 0 Max: 29329 Err: 879 (27.54%)
# Tidying up ... @ Sun Feb 21 15:40:52 CST 2021 (1613893252759)
# ... end of run
运行结束后我们在输出中输出报告,打开index.html
即可。
3.3.5报告分析
首先我们看到Dashboard-Statistics
,这里我们可以查看聚合报告的内容。
1、错误率为44.99% > 0.06%
2、RT 的标准,我们关注95%和99%的响应时间
这里的两个时间23268ms
和27705ms
大于500ms
3、TPS和QPS的向我们上面说的我们区分接口得出TPS和QPS
TPS(下单、支付) 7.97 + 4.11 + 7.77 = 19.85 小于 500
QPS 71.44-19.85=51.59 < 2747
这里我们知道存在大的性能问题,我们可以接着查看下面的errors图表
查看已知错误,这里可以看到都是链接服务器时的错误。(这里我尝试修改了fd的连接数和ulimit。也没解决问题,) 在错误率居高的情况下我们先解决服务器的错,否则分析是没有效果的。
由于这里没法调优,我们直接分析一下成功的性能问题。
-
响应时间变化趋势图
我们首先看RT在大量vu涌入后,头一分钟还是比较离散的,在下一分钟后,多数的请求RT整体飙高了一倍,然后收缩到10s-8s之间。
-
响应延时变化趋势图
这里的响应延时和响应时间一致,可以看出服务器本身很大的问题,大量的阻塞影响到服务器返回。
-
吞吐量
这里和响应时间变化趋势图基本一致,没有过多分析
-
平均响应时间和线程数的对应变化曲线
在这个图我们可以看出,有很多突然飙高的节点的,这基本可以确定是系统存在阻塞,导致在请求涌入是阻塞,当线程不请求服务器时,整个响应时间就下来了。
4、结语
本篇文章,有很多不成熟的地方。希望给位大佬指正。