Skip to content

jmeter使用

安装并运行

测试环境用的测试脚本

以下测试是test.jmx文件使用JSR223脚本测试json解析效率:

xml
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <intProp name="LoopController.loops">-1</intProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">8</stringProp>
        <stringProp name="ThreadGroup.ramp_time">0</stringProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
      </ThreadGroup>
      <hashTree>
        <JSR223Sampler guiclass="TestBeanGUI" testclass="JSR223Sampler" testname="JSR223 Sampler" enabled="true">
          <stringProp name="cacheKey">true</stringProp>
          <stringProp name="filename"></stringProp>
          <stringProp name="parameters"></stringProp>
          <stringProp name="script">import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

String JSON=&quot;{\&quot;errorCode\&quot;:0,\&quot;errorMessage\&quot;:null,\&quot;dataObject\&quot;:\&quot;你好\&quot;}&quot;;
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(JSON);
int errorCode = node.get(&quot;errorCode&quot;).asInt();
if(errorCode&gt;0) {
	vars.put(&quot;registerSuccess&quot;,&quot;false&quot;);
}else {
	vars.put(&quot;registerSuccess&quot;,&quot;true&quot;);
}</stringProp>
          <stringProp name="scriptLanguage">groovy</stringProp>
        </JSR223Sampler>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

dcli安装jmeter master模式

  1. 安装dcli命令行工具

    bash
    sudo rm -f /usr/bin/dcli && sudo curl https://fut001.oss-cn-hangzhou.aliyuncs.com/dcli/dcli-linux-x86_64 --output /usr/bin/dcli && sudo chmod +x /usr/bin/dcli
  2. 安装jmeter master

    bash
    sudo dcli jdk install && sudo dcli jmeter install
    
    # 在提示中选择master模式
  3. 运行jmeter测试,注意:test.jmx内容是上面提到的测试脚本。

    bash
    jmeter -n -t test.jmx

dcli安装jmeter master slave模式

  1. 安装dcli命令行工具

    bash
    sudo rm -f /usr/bin/dcli && sudo curl https://fut001.oss-cn-hangzhou.aliyuncs.com/dcli/dcli-linux-x86_64 --output /usr/bin/dcli && sudo chmod +x /usr/bin/dcli
  2. master虚拟机中安装jmeter master

    bash
    sudo dcli jdk install && sudo dcli jmeter install
    
    # 选择master模式
    # remote_hosts填写所有jmeter slave ip地址
  3. slave虚拟机中安装jmeter slave

    bash
    sudo dcli jdk install && sudo dcli jmeter install
    
    # 选择slave模式
    # rmi监听ip地址填写slave本机ip地址,因为master需要使用rmi端口和slave通讯
  4. master中启动分布式测试,注意:192.168.235.144jmeter slaveip地址

    bash
    jmeter -n -t test.jmx -R 192.168.235.144
  5. 停止测试

    bash
    ./stoptest.sh

单机测试

注意:使用dcli安装jmeter master模式。

使用/home/xxx/xxx.jmx文件启动jmeter测试

bash
jmeter -n -t /home/xxx/xxx.jmx

判断是否硬件瓶颈导致jmeter分布式测试无法提高性能

在研究jmeter分布式测试性能过程中,会遇到这样的情况:使用笔记本电脑启动多台虚拟机用于部署jmeter集群,但是在测试过程中继续添加更多的虚拟机后QPS却无法提升,这是因为笔记本电脑单机性能达到瓶颈。

怎么测试笔记本电脑单机性能达到瓶颈呢?可以通过创建多个虚拟机分别运行单机版的jmeter,通过此方法找出笔记本电脑最多运行多少个jmeter虚拟机就达到性能瓶颈。

非基于kubernetesjmeter分布式测试

注意:使用dcli分别在master虚拟机上安装jmeter master模式,在slave虚拟机上安装jmeter slave模式。

使用/home/xxx/xxx.jmx文件启动分布式jmeter测试

bash
# 启动所有远程主机分布式测试
jmeter -n -t /home/xxx/xxx.jmx -r

# 启动指定远程主机分布式测试
jmeter -n -t /home/xxx/xxx.jmx -R 192.168.1.1,192.168.1.2

停止分布式测试,注意:不能关闭master进程,否则master无法接收停止信号转发给slave以达到停止测试

jmeter-stop-remote-server

bash
# 停止分布式测试
./shutdown.sh

# 停止分布式测试
./stoptest.sh

基于kubernetesjmeter分布式测试

注意:推荐使用这个方式运行jmeter分布式测试,因为方便部署和管理。

Load Testing With Jmeter On Kubernetes and OpenShift

jmeter slaveDaemonSet方式在kubernetes集群中运行。

示例的详细用法请参考 链接

运行示例步骤:

  1. 搭建openresty目标,用于协助jmeter性能测试,参考链接

  2. 因为此jmeter支持自定义RedisBenchmarkSampler插件用于性能测试redis,所以需要先编译此插件 链接

    bash
    # 编译插件命令
    mvn package
  3. 编译docker镜像

    bash
    ./build-images.sh
  4. 推送docker镜像

    bash
    ./push-images.sh
  5. 搭建kubernetes集群,参考链接

  6. ubuntu配置kubectl客户端以直接在ubuntu上运行jmeter分布式测试,参考链接

  7. 启动测试

    bash
    ./start_test.sh jmeter.jmx
  8. 测试期间通过http://192.168.1.10:30001(其中192.168.1.10k8s集群的任何一个节点ip地址)登录openresty目标grafana查看压力测试相关数据

  9. 测试期间通过http://192.168.1.10:30000/(其中192.168.1.10k8s master节点的ip地址)登录jmetergrafana查看jmeter监听器上报的测试数据

  10. 停止测试

bash
./stop_test.sh

基于kubernetes和非基于kubernetesjmeter分布式测试结果对比

实验配置如下:

  • jmeter master/k8s master虚拟机centOS8-stream,4核(无限制CPU)+8G内存
  • 3台jmeter slave/k8s worker虚拟机centOS8-stream,2核(最高4400MHz CPU频率)+4G内存

实验结果:

  • 基于kubernetes QPS最高50k/s左右
  • 非基于kubernetes QPS最高59k/s左右

实验结论:非基于kubernetes性能高于基于kubernetes环境,可能是由于jmeter运行容器环境性能有所降低或者kubernetes flannel网络性能不如虚拟机之间直接通讯的网络性能高导致(todo:未排查得到证据证明这个猜想)。但是总体基于kubernetes环境的性能损耗还是在可接受范围内的。

GCP平台测试基于kubernetesjmeter分布式压测结果

实验配置如下:

  • 1台k8s master虚拟机centOS8-stream,虚拟类型e2+4核+8G内存
  • 5台k8s worker虚拟机centOS8-stream,虚拟类型e2+4核+8G内存
  • 1台openresty辅助测试目标虚拟机centOS8-stream,虚拟类型e2+16核+16G内存

实验结果:QPS稳定在164k/s

实验结论:GCP平台上压测每台k8s worker能够产生约32k/sQPSjmeter集群产生的总QPSk8s worker数量成正比的。

jmeter调优

调整堆内存

编译/usr/local/jmeter/bin/jmeter添加HEAP="-Xms2g -Xmx2g"# resolve links之后。

分布式测试调优jmeter结果样本sender模式

JMeter mode setting : Helps in optimizing the load generation

Using a different sample sender

测试计划中的监听器将结果发送回客户端JMeter,后者将结果写入指定文件。默认情况下,样本在生成时同步发送回。这可能会影响服务器测试的最大吞吐量;在线程可以继续之前,必须返回采样结果。可以设置一些JMeter属性来改变这种行为。

  1. 设置statistical模式

    此模式主要用于汇总采样,不采样所有字段。此外,采样率取决于批处理模式所描述的属性。样品将根据线组名称和样品标签进行分组。它只累积以下字段,其他字段在样本之间的变化将被忽略: 将累积的字段为:1。时间流逝,2。延迟,3。字节数,4。样本计数和5。错误计数。 这种模式在一定程度上减少了样本数据对网络的影响,并且在分布式环境中也将使用更少的客户端资源。因此,建议在考虑客户端系统性能、网络性能等因素后设置有效阈值。

    注意:经过测试设置此模式进行分布式测试单slave节点性能和单机jmeter性能相当

    编辑/usr/local/jmeter/bin/jmeter.properties设置mode=Statistical

  2. 设置num_sample_threshold阈值,以减少压力测试样本回传次数导致测试间隙停顿。

    编辑/usr/local/jmeter/bin/jmeter.properties设置num_sample_threshold=81920

使用docker运行jmeter+influxdb+grafana

JMeter的基本使用(jmeter+influxDB+Grafana)

提醒:grafana dashboards JSON文件是通过手动导入https://grafana.com/grafana/dashboards/5496第三方模板后再导出为JSON得到的。

示例的详细配置请参考 链接

jmeter+influxdb+grafana是为了图形化显示jmeter压测结果。

运行步骤:

  • 编译镜像

    bash
    docker compose build
  • 运行示例

    bash
    docker compose up -d
  • 访问grafana http://localhost:3000/查看jmeter压测状态

  • 启动测试制造influxdb+grafana数据

    bash
    ./start_test.sh

todo jmeter单机性能调优

todo:搜索一篇外国资料描述jmeter单机或者分布式测试的性能调优博客。调优后使得jmeter分布式测试在相同的硬件配置下发挥出更高的性能。

todo:centos8 系统优化 centos内核优化(在gcp中测试jmeter时,测试以下配置是否有调优效果)https://blog.51cto.com/u_16099314/10091045

1、内存
2、线程数
3、调整Stastic
4、queue size=8192

调整jmeter日志级别

在开发插件过程中,需要调整jmeter日志级别为DEBUG以打印插件调试信息,参考链接

通过jmeter菜单修改日志级别,Options>Log Level>DEBUG