使用阿里云性能测试工具 JMeter 场景压测 RocketMQ 最佳实践!

1241 篇文章 6 订阅
1155 篇文章 2 订阅

需求背景

Cloud Native

新业务上线前,我们通常需要对系统的不同中间件进行压测,找到当前配置下中间件承受流量的上限,从而确定上游链路的限流规则,保护系统不因突发流量而崩溃。阿里云 PTS 的 JMeter 压测可以支持用户上传自定义的 JMeter 脚本,按照自定义的逻辑,借助 PTS 强大的分布式压测能力,对系统的不同中间件进行压测。下面,将以 JMeter5.5 和 RocketMQ5.0 系列为例,详细介绍如何使用 PTS 的 JMeter 场景压测 RocketMQ。

前置条件

Cloud Native

1. 已在本地安装 JMeter。

2. 已在阿里云 ECS 上部署 RocketMQ(本文选择的是一台 8C32G 规格的 ECS)。

3. 已在阿里云上开通 PTS 服务。

压测过程

Cloud Native

JMeter 提供了扩展性极强的 JavaSampler,我们可以通过继承 AbstractJavaSamplerClient 类来自定义在 JavaSampler 中执行的逻辑,从而实现对 RocketMQ 进行压测。

1、步骤一:创建 Maven 项目,并引入依赖

1. 新建 Maven 工程,并在 pom 文件中引入下面的依赖:

<dependency>  <groupId>org.apache.jmeter</groupId>  <artifactId>ApacheJMeter_java</artifactId>  <version>5.5</version>  <scope>provided</scope></dependency><dependency>  <groupId>org.apache.rocketmq</groupId>  <artifactId>rocketmq-client</artifactId>  <version>4.9.5</version></dependency>

ApacheJMeter_java 是 JMeter JavaSampler 的依赖,rocketmq-client 是 RocketMQ 的客户端依赖(此处用 4.x 版本是因为 4.x 版本的客户端可以兼容 5.x 版本的服务端实例,但是 5.x 版本的客户端不能兼容 4.x 版本的服务端实例,可根据自己需求调整)。其中,要注意的是 ApacheJMeter_java 依赖的 scope 定义为  provided,JMeter 的 lib/ext 目录下已有该 JAR 包,因此不必将该依赖一起打包。

2. 在 pom 文件中引入 maven-assembly-plugin 插件,此处使用 “jar-with-dependencies” 打包方式,将项目所需依赖和项目代码打包到同一个 JAR 包,后续可以只上传该 JAR 包到 PTS 的 JMeter 环境中,不用上传多个依赖 JAR 包:

<build>  <finalName>jmeter-rocketmq4</finalName>  <plugins>    <plugin>      <artifactId>maven-assembly-plugin</artifactId>      <version>3.4.2</version>      <configuration>        <!-- 打包方式 -->        <descriptorRefs>          <descriptorRef>jar-with-dependencies</descriptorRef>        </descriptorRefs>      </configuration>      <executions>        <execution>          <id>make-assembly</id>          <phase>package</phase>          <goals>            <goal>single</goal>          </goals>        </execution>      </executions>    </plugin>  </plugins></build>

2、步骤二:新建 AbstractJavaSamplerClient 的子类,并重写相关方法

AbstractJavaSamplerClient 类继承了 JavaSamplerClient 接口,该接口包含 setupTest、runTest、teardownTest 和 getDefaultParameters 四个方法:

  • setupTest

    JMeter 将为测试中的每个线程创建一个 JavaSamplerClient 实现实例,测试开始时,将在每个线程的 JavaSamplerClient 实例上调用 setupTest 来初始化客户端,本例中即初始化 RocketMQ 的 producer。

  • runTest

    每个线程每次迭代会调用一次 runTest 方法,本例中,需要在 runTest 方法里面定义消息发送的方法和采样结果的设置逻辑。

  • teardownTest

    迭代完设置的次数或时间后,此方法将会被执行,本例中,需要在此方法关闭 producer。

  • getDefaultParameters

    此方法定义了参数列表,这些参数通过会 JavaSamplerContext 传递给上述方法方法,在此方法内定义的参数,可以在 JMeter JavaRequest Sampler 的 GUI 界面设置值,本例中,需要定义 RocketMQ 的 broker 地址、topic 名称、消息 key、消息内容等参数。

新建子类参考如下:

import java.nio.charset.StandardCharsets;import org.apache.jmeter.config.Arguments;import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;import org.apache.jmeter.samplers.SampleResult;import org.apache.rocketmq.client.exception.MQBrokerException;import org.apache.rocketmq.client.exception.MQClientException;import org.apache.rocketmq.client.producer.DefaultMQProducer;import org.apache.rocketmq.client.producer.SendResult;import org.apache.rocketmq.common.message.Message;import org.apache.rocketmq.remoting.exception.RemotingException;
public class JavaSamplerForRocketMQ extends AbstractJavaSamplerClient {    private DefaultMQProducer producer;    private static final String NAME_SRV_ADDRESS = "nameSrvAddress";    private static final String TOPIC = "topic";    private static final String PRODUCER_GROUP = "producer group";    private static final String MSG_BODY = "messageBody";    private static final String MSG_KEY = "messageKey";    private static final String MSG_TAG = "messageTag";    private static final String ERROR_CODE = "500";
    @Override    public void setupTest(JavaSamplerContext javaSamplerContext) {
        try {            // 初始化producer            producer = new DefaultMQProducer(javaSamplerContext.getParameter(PRODUCER_GROUP));            producer.setNamesrvAddr(javaSamplerContext.getParameter(NAME_SRV_ADDRESS));            producer.start();        } catch (MQClientException e) {            throw new RuntimeException(e);        }
    }
    @Override    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {        SampleResult sampleResult = new SampleResult();        sampleResult.setSampleLabel("rocketmq-producer");        // 请求开始        sampleResult.sampleStart();        // 普通消息发送        Message message = new Message(            javaSamplerContext.getParameter(TOPIC),            javaSamplerContext.getParameter(MSG_TAG),            javaSamplerContext.getParameter(MSG_BODY).getBytes()        );        try {            // 发送消息,需要关注发送结果,并捕获失败等异常。            SendResult sendResult = producer.send(message);            // 设置发送请求的字节数            sampleResult.setSentBytes(message.toString().getBytes(StandardCharsets.UTF_8).length);            sampleResult.setDataType(SampleResult.TEXT);            // 设置请求内容            sampleResult.setSamplerData(message.toString());            // 设置响应内容            sampleResult.setResponseData(String.format("Msg Id:%s", sendResult.getMsgId()).getBytes());            sampleResult.setSuccessful(true);            sampleResult.setResponseCodeOK();        } catch (MQBrokerException | InterruptedException | RemotingException | MQClientException e) {            sampleResult.setSuccessful(false);            sampleResult.setResponseCode(ERROR_CODE);            sampleResult.setResponseData(String.format("Error Msg:%s", e).getBytes());            return sampleResult;        } finally {            // 请求结束            sampleResult.sampleEnd();        }        return sampleResult;    }
    @Override    public void teardownTest(JavaSamplerContext javaSamplerContext) {        producer.shutdown();    }
    @Override    public Arguments getDefaultParameters() {        Arguments arguments = new Arguments();        arguments.addArgument(NAME_SRV_ADDRESS, "");        arguments.addArgument(PRODUCER_GROUP, "");        arguments.addArgument(TOPIC, "");        arguments.addArgument(MSG_KEY, "");        arguments.addArgument(MSG_TAG, "");        arguments.addArgument(MSG_BODY, "");        return arguments;    }}
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

3、步骤三:打包项目成 JAR 文件

通过 mvn clean package 将项目打包,在 target 目录中可见 jmeter-rocketmq4.jar 和 jmeter-rocketmq4-jar-with-dependencies.jar 两个 JAR 包,其中 jmeter-rocketmq4-jar-with-dependencies.jar 包括了所需的依赖,在后续步骤中使用此 JAR 包。

.├── pom.xml├── src│   ├── main│   │   ├── java│   │   │   └── JavaSamplerForRocketMQ4.java│   │   └── resources│   └── test│       └── java└── target    ├── jmeter-rocketmq4-jar-with-dependencies.jar    ├── jmeter-rocketmq4.jar

4、步骤四:使用 JMeter GUI 进行脚本编写和调试

1. 将打包好的 JAR 包和依赖的 JAR 包复制到 JMETER_HOME/lib/ext 目录下,然后执行命令 JMETER_HOME/bin/jmeter 打开 JMeter GUI。

2. 新建线程组后添加 Java 请求取样器。

图片

3. 在下拉框中选择步骤二中新增的类(不一定和图片中的完全一致,按照实际的类全限定名选择),并填写下方相关参数。

图片

4. 为线程组添加“查看结果树”和“汇总报告”监听器,然后启动测试计划,在结果树和汇总报告中验证测试的结果是否符合预期。

5. 保存该测试计划为 JMX 文件。

5、步骤五:在 PTS 创建 JMeter 场景进行压测

1. 在 PTS 控制台创建 JMeter 环境,将步骤三中打包的 JAR 包上传到该 JMeter 环境中(更多细节请参考 JMeter 环境管理的查看、修改及创建_性能测试-阿里云帮助中心[1]):

a. 进入 PTS 控制台,选择“JMeter 环境”;

b. 输入自定义的环境名;

c. 点击上传文件,选择步骤三中打包的 JAR 包;

d. 点击保存。

图片

2. 在 PTS 控制台创建场景中选择“JMeter 压测”场景:

图片

3. 编辑“场景配置”:

a. 自定义场景名;

b. 点击上传文件,选择步骤四中保存的 JMX 文件;

c. 在“使用依赖环境?”下拉框中选择“是,使用依赖环境”;

d. 在“选择依赖环境”下拉框选择刚刚创建的 JMeter 环境。

图片

4. 施压配置:

小建议:

由于我们是想通过压测找到 RocektMQ 能承受的最大并发请求数,因此建议选择 RPS 模式,这样可以直接衡量 RocektMQ 的承压能力。同时,考虑到公网带宽限制,应该选择阿里云 VPC 内网压测。

a. 选择压力来源为阿里云 VPC 内网,同时选择部署被压测 RocketMQ 的 ECS 所在区域;

b. 设置 ECS 的 VPC、安全组和交换机,注意 VPC 和安全组一定要和 ECS 相同,安全组中要打开响应的端口(在 ECS 控制台设置);

c. 设置压力模式为 RPS 模式;

d. 设置起始 RPS、最大 RPS 和压测时长,本文设置起始 RPS 为 90000,最大 RPS 为 110000,持续 2 分钟。

e. 指定循环一般设置为否,表示执行一次就结束,指定 IP 数会根据设置的 RPS 自动生成。

图片

5. 其余设置请根据需求参考 JMeter 压测_性能测试-阿里云帮助中心[2]

6. 保存配置并调试场景,确认和 RocketMQ 的连通,之后可以开始进行压测。

6、步骤六:查看压测报告

JMeter 的压测报告通用解读可以参考如何查看 JMeter 压测数据、采样日志及施压机性能_性能测试-阿里云帮助中心[3],下一节将介绍如何使用 PTS 的压测报告来找到 RocketMQ 的承压能力。

报告解读

Cloud Native

1. 首先,查看整个压测的概览信息和指标趋势。如下图所示,报告第一栏展示了整个压测过程的请求成功率、平均 RT、平均 TPS 等指标,这些指标可以在官方文档中找到具体解释。同时,根据成功率的趋势图所示,从 18:54:05 开始,成功率逐渐波动下降,此时的 TPS 值为 9.55W,代表 18:54:05 计算的前 5 秒平均 TPS 约为 9.55W。

图片

2. 其次,使用压测报告中的 Prometheus 监控数据对结果进一步分析。借助阿里云 ARMS 的 Prometheus 和 Grafana 产品,PTS 的压测报告可以提供包括吞吐量、成功率和响应时长的时序图,同时,支持用户使用 PromQL 语句对数据面板进行编辑操作,灵活查询所需的数据,在本文中,我们可以将成功率和吞吐量放在一个 panel,来进一步分析。

a. 首先点击“成功率(时序)”,然后点击“Edit”,可进入成功率大盘的编辑界面,复制成功率的查询 PromQL:

sum(rate(pts_api_response_total{task_id="$task_id", code=~"200|302"}[5s]))/sum(rate(pts_api_response_total{task_id="$task_id"}[5s]))

图片

b. 然后进入吞吐量大盘的编辑界面,使用成功率的 PromQL 替换虚拟用户数的 PromQL,并更改 Grafana 的相关配置(下图中红框),便可得到展示吞吐量和成功率的面板。

图片

该面板展示的数据统计精度为 1 秒,可得到更精确的数据,在 18:54:05 秒时,成功率开始下降,此时 TPS 为 96561.9。

图片

c. 为了更好的评估 RocketMQ 的性能,我们还可以统计出成功率保持 100% 的时间范围内的平均 TPS,首先找到成功率为 100% 的持续时间,下图中为 47 秒,然后将计算 TPS 的指标的时间范围改成 47s,这样每个点都代表前 47s 的平均 TPS,将鼠标移动到成功率为 100% 的最后一个时间,当前时间的 TPS 值即为成功率为 100% 时间范围内的平均 TPS,即 89357.5。

图片

图片

3. 最后,为了对比不同参数的设置对 RocketMQ 性能的影响,同时验证 PTS 在 RocketMQ 压测上的可用性,我们做了一个简单的对比实验,并通过 jstat 命令来观察不同参数对垃圾回收的影响。

图片

实验结果显示,对于当前 ECS 配置部署的 RocketMQ,适当调大堆内存可以有效提高 RocketMQ 的性能,当堆内存提高到 24g 时(此事 ECS 内存使用率达到 85.39%),性能没有显著提高;适当提高 sendMessageThreadPoolNums 的值可以提高 RocketMQ 的性能,当 sendMessageThreadPoolNums 超过 16 后,性能没有显著提高,甚至略有下降。用户可以根据实际情况,进行更详细的对比实验,来充分评估所部署的 RocketMQ 承压能力。

结束语

Cloud Native

本文介绍了使用阿里云 PTS 的 JMeter 场景压测 RocketMQ 的详细步骤,对各环节逐一进行了说明,最后,通过对压测报告的自定义分析,展现了 PTS 强大的压测结果分析能力,借助 JMeter 和 PTS,用户可以对各类中间件进行灵活多维的分析,助力其构建起稳定健壮的系统。

最新活动&免费试用

性能测试 PTS 基础版火热售卖

性能测试 PTS 推出全新的售卖规格,最高 5 万用户并发量,压测额度 3 万 VUM,满足中小企业容量规划、服务测试等日常需求,仅需 59.9 元。

图片

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
 

在这里插入图片描述

### 回答1: JMeter是一款用于性能测试的自动化工具,而RocketMQ则是一款高可用性、高性能的分布式消息传递系统。为了帮助用户更好地测试并优化RocketMQ性能,社区开发了jmeter压测rocketmq的插件。 该插件主要包括两个部分,一个是Sampler,用于向RocketMQ发送消息,并返回发送成功或失败的结果;另一个是Listener,用于接收RocketMQ发送的消息,并统计收到的消息数量以及响应时间等性能指标。 使用该插件可以方便地模拟高并发场景RocketMQ性能表现,并通过测试结果来优化系统的性能。此外,该插件还支持自定义消息发送频率、批量发送等多种参数设置,可以根据实际需求进行调整。 需要注意的是,使用该插件需要具备一定的JMeterRocketMQ使用经验,并了解相关性能测试理论以及测试工具使用方法。同时,也需要确保测试环境的稳定性以及测试数据的真实性,以获得准确的测试结果。 总之,jmeter压测rocketmq的插件为用户提供了一种便捷的测试工具,可以帮助用户更快速、更准确地进行RocketMQ性能测试和优化。 ### 回答2: JMeter是目前应用比较广泛的Java软件负载性能测试工具,而RocketMQ是一款开源的分布式消息队列系统。那么,JMeter压测RocketMQ需要使用哪些插件呢? 首先,为了实现对RocketMQ负载测试,需要加入jmeter-rocketmq的插件。这个插件通过使用RocketMQ的Java客户端类库来发送消息并进行真正的压测。在此之前,需要先安装RocketMQ的Java客户端类库,并在JMeter的类路径中配置。 接着,需要在JMeter的用户定义变量中设置RocketMQ的地址和端口号。例如,定义了名为'mq_host'和'mq_port'的两个变量,值为'rocketmq.example.com'和'9876'。此外,还需要设置RocketMQ的Topic和Consumer Group。 然后,在JMeter中添加RocketMQ的Sampler和Listener,这些组件可以在JMeter的组件面板中找到。Sampler用于发送消息,而Listener则用于接收响应消息。在Sampler中,需要设置RocketMQ的发送消息的内容、消息类型和消息的主题等相关参数。 最后,启动压测,结果可以通过Listener组件来查看。这里可以查看到消息的发送和接收数、响应时间等相关信息。 总的来说,JMeter压测RocketMQ需要使用jmeter-rocketmq插件,同时还需要对插件进行配置和设置实现对RocketMQ负载测试。通过这些步骤,可以实现对RocketMQ进行比较全面的性能测试和评估。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值