

在全链路压测:压测平台改造一文中讲了几个和传统压测之间的区别以及相应的压测平台改造点,本文主要讲述改造点中关于TPS的动态调整以及全链路压测平台原型部分实现。


TPS调整
TPS调整主要思路来源于阿里巴巴本地生活前高级专家吴骏龙的付费文章,有些地方还是没有满足个人压测经历的需求,本节内容做了改动以适配后续压测平台设计
全链路压测如果使用JMeter作为压力引擎,受限于JMeter的压力发起机制,需要进行一些配置以具备实时调整TPS的能力,具体实现可基于以下:
1、修改jmeter.properties文件,启用如下标记的配置项,修改后,启动jmeter时会开启Beanshell服务器,两个端口9000(httpd)和9001(telnet),以支持步骤4中的命令运行。


2、编写beanshell脚本,命名为tpschange.bsh,可自定义
import org.apache.jmeter.util.JMeterUtils;setprop(p,v){// set your TPSprint("Setting link '"+p+"' tps to '"+v+"'.");JMeterUtils.getJMeterProperties().setProperty(p, v);}if (Integer.parseInt(args[1]) <= Integer.parseInt(args[2])){setprop(args[0],args[1]);}else{setprop(args[0],args[2]);}
3、运行的JMX脚本


4、执行命令
java -jar %JMETER_HOME%/lib/bshclient.jar localhost 9000 E:\jmx\tpschange.bsh api1 5 500
5、命令解释
java -jar %JMETER_HOME%/lib/bshclient.jar localhost 9000,localhost可基于用户申请的压测机IP进行替换代入。
E:\jmx\tpschange.bsh,beanshell脚本路径,可维护一个唯一路径,内容保持不变,需要改变时应通过统一入口进行管理批量更新。
api1为接口ID,此ID应保持全平台永久唯一,用户确认调整TPS后命令中需将此ID代入args[0]进行指定接口TPS调整。
数字5为期望设置的TPS值,此处应该考虑多台机器分布式测试的情况,如用户使用5台机器进行分布式测试,命令中args[1]值统一换算公式应该为:用户输入的TPS/N (N为申请的压测机的数量)。
数字500为限制该接口链路的TPS值,单台机器能支撑的TPS是有限的,用户可以在一定范围内自定义输入TPS值,超过限制值后应使输入的TPS等于限制TPS值,对应命令中args[2]值, 统一换算公式应该为:
args[2]=(用户输入的当前线程组的TPS/当前JMX脚本包含的所有线程组TotalTps)*压测平台约定单机限制的TPS.
单机限制的TPS在全链路压测平台中应该配置成可维护的全局配置,可结合具体情况测试和微调。
6、运行效果截图
interfaceA:5TPS>20TPS>3TPS>END
interfaceB:10TPS>30TPS>1TPS>END

结合上图左右部分图示,可以看到初始TPS后的动态调整过程。


压测平台原型

当某个接口进行性能测试,需要调整TPS时只需要点击TPS调整按钮,弹出接口信息以及TPS调整输入框,点击确认(3)后,平台代码调用命令进行TPS动态调整。


并发线程数
以上,讲述了TPS动态调整过程,你是否有考虑,并发线程数怎么调整?提到这个点是因为工作经历中,一方面领导层经常对工具中的并发线程数,系统能支撑多少人访问,TPS之间的关系有疑问。另一方面是JMeter的很多线程组都是通过预先设置并发线程数去进行压测,这种模式存在很多弊端,不适用于全链路压测中。
在这里放出一个公式,供大家理解:TPS=(1/RT)*VU,RT为响应时间,1为1秒,如果RT的单位为秒,那么公式中这个数字就是1,如果RT的单位为毫秒,那么公式中的数字是1000,VU为虚拟用户数对应JMeter中并发线程数。
在压测中我们关注的强指标是TPS和RT,个人理解VU只是一个加压力的手段,TPS是我们期待某个系统应该要达到的值,我们直接动态调整该值去测试系统能否达到,同时RT也会在不同TPS值下通过JMeter的压测结果知道,上述公式中一共3个变量,我们知道了两个,那么VU值自然就知道了。本例中的VU图,是结果,没有人为去调整:

本文中演示的bzm - Arrivals Thread Group线程组让用户只通过调整TPS就可以知道RT和VU值,无需关注VU应该怎么去设置,原因在于它可以在已有的线程是繁忙的状态下去创建线程以支撑更大压力发起:
It will create new threads if all existing threads are busy in the middle of iterations.
该线程组为BlazeMeter Inc受到Dynatrace LLC 启发,开发出来的组件并贡献给开源社区,建议采用该线程组去进行全链路压测。



全链路压测
在性能测试工程师维护好需要压测的接口后,对单接口进行逐个压测,在确认单个接口无性能问题后,可组织全链路压测,只需要将单接口进行集合后生成测试方案,这些测试方案可以基于整个公司、集团科技的业务来进行归类,比如常见的电商网站分为用户登录,商品加入购物车,下单,支付,查询订单,查询物流,客服沟通等业务环节,同业务模块的接口整合到同一方案中,一旦开始全链路压测,这些方案中的接口均需启动进行压测,不同方案压测高峰期会有先后顺序差异,如前10分钟用户可能忙于下单支付,过了一天后才会高并发去查询物流信息等,全链路压测也应该按照这种错峰模型去压测以更加接近真实情况,错峰只是模拟真实业务场景错开高峰期,并不是完全的压或者不压测某一环节,所有环节(方案)应该在全链路开始后均启动压测。
测试方案如何集合同一模块的业务接口(脚本)?本文中初步设计为,类似JMeter GUI模式下,脚本聚合(Merge)操作,用户通过下拉框(下图步骤3)选中需要归类到同一方案中的接口后,点击创建,压测平台自动进行聚合操作生成一个JMX文件,该JMX文件包含了多个线程组,多个接口:


点击方案中的压测控制台,即可进入方案执行页面:

结合文中压测平台原型图,JMX脚本,beanshell脚本中内容,可以发现接口ID串联起来了整个压测平台中涉及的内容:压测平台生成接口ID api1、api2,对应JMX脚本中控制TPS设置的属性名,该属性名传入beanshell脚本中属性名p;平台代码获取用户在前端页面输入的TPS值(v)来控制对应接口的TPS值;每个方案ID下是多个接口ID的集合,在每个方案下我们可以动态地去选择、调整想要调整的接口的TPS值。



本文讲述了TPS的动态调整过程以及具体的压测平台原型设计,之后描述了全链路压测方案在单接口基础上的创建过程以及创建后的压测操作,可以让用户在性能测试项目中极大减少不必要的操作,也可以让全链路压测操作更安全。
以上是我所经历的全链路压测的一点总结,如果喜欢,请转发和关注




