jmeter外掛開發—RocketMQ4.9

第二个卿老师發表於2024-07-03

上期是使用java測試了rocketmq中介軟體的測試,考慮到後期效能測試,準備封裝為jmeter外掛。參考TesterHome的文章

環境說明

JDK1.8.0,Jmeter 5.4.3,maven構建工具(使用JDK17時遇到過跟Jmeter設定的外觀有衝突)

實現程式碼(pom.xml已貼在上期的文章最後)

以下為全部程式碼,可以自行調整相關引數,實現了普通send與oneway(單向)的傳送方式

package com.qgc.maven;

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.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import com.alibaba.fastjson.JSONObject;
import java.io.UnsupportedEncodingException;


public class JmeterMqProducer extends AbstractJavaSamplerClient {
    //這裡定義類變數(不能定義為static,會報錯)
    private DefaultMQProducer producer;
    private String producerName;
    private String producerGroup;
    private String serverUrl;
    private String topic;
    private String tags;
    private String keys;
    private String body;
    private String delayTime;
    private String timeout;
    private String sendType;
    private long cur_time;
    private byte[] bodyBytes;
    private String orginData;
//    private final Logger log = LogManager.getLogger(JmeterMqProducer.class);

    //這裡定義這裡作為請求的前置處理
    @Override
    public void setupTest(JavaSamplerContext context) {
        serverUrl = context.getParameter("serverUrl");
        topic = context.getParameter("topic");
        tags = context.getParameter("tags");
        keys = context.getParameter("keys");
        body = context.getParameter("messageBody");
        bodyBytes = body.getBytes();
        producerName = context.getParameter("producerName");
        producerGroup = context.getParameter("producerGroup");
        timeout = context.getParameter("timeout");
        sendType = context.getParameter("sendType");
        delayTime = context.getParameter("delayTime");

        try {
            producer = getProducer(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    //這裡自定義了一個Producer的單例方法
    public DefaultMQProducer getProducer(int type) throws InterruptedException {
        if (producer == null){
            producer = new DefaultMQProducer(producerName);
            if (type == 1){
                System.out.println("=======init producer =====");
                cur_time = System.currentTimeMillis();
            }else {
                System.out.println("=======runtest producer =====");
            }
            producer.setNamesrvAddr(serverUrl); //serverUrl
            // 設定超時時間
            producer.setSendMsgTimeout(Integer.parseInt(timeout));
        }
        try {
            producer.start();
        } catch (MQClientException e) {
            System.out.println("啟動init!忽略");
        }
        return producer;
    }

    //這裡是一個請求結束的後置處理
    @Override
    public void teardownTest(JavaSamplerContext context) {
        producer.shutdown();
    }

    //這裡是一個請求主體執行部分
    @Override
    public SampleResult runTest(JavaSamplerContext context) {

        SampleResult sr = new SampleResult();
        sr.sampleStart();
        Message msg = null;
        try {
            msg = new Message(topic, tags, keys, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        try {
            JSONObject json = new JSONObject();
            json.put("serverUrl", serverUrl);
            json.put("sendType", sendType);
            json.put("topic", topic);
            json.put("tags", tags);
            json.put("keys", keys);
            json.put("producerName", producerName);
            sr.setRequestHeaders(json.toString());
            sr.setSamplerData(body);
            if ("oneWay".equals(sendType)){
                producer.sendOneway(msg);
                sr.setResponseData("{\"code\": \"200\", \"SendStatus\" : \"success\"}","utf-8");
            }else {
                SendResult sendResult = producer.send(msg);
                sr.setResponseData(sendResult.toString(),"utf-8");
                if(sendResult !=null || sendResult.getSendStatus() == SendStatus.SEND_OK){
                    sr.setResponseData("{\"code\": \"200\", \"SendStatus\" : \"" + sendResult.getSendStatus() + "\",\"MsgId\" : \"" + sendResult.getMsgId() +"\"}","utf-8");
                }
                else {
                    System.err.println(sendResult);
                    sr.setResponseData("{\"code\" : \"500\", \"msg\": \"失敗\", \"Error\": \""+ sendResult.toString() +"\"}","utf-8");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            sr.setResponseData("{\"code\" : \"501\", \"msg\": \"其他失敗\", \"Error\": "+ e +"}","utf-8");
            producer.shutdown();

        }
        try {
            sr.setDataType(SampleResult.TEXT);
            sr.setSuccessful(true);
        }catch(Exception e){
            sr.setSuccessful(false);
            e.printStackTrace();
        }
        finally {
            sr.sampleEnd();
        }
        return sr;

    }

    // 給引數填充預設值
    @Override
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("serverUrl", "18.162.xxx.xx:9876");
        params.addArgument("topic", "qgc_TopicTest");
        params.addArgument("tags", "qgc_TagA");
        params.addArgument("keys", "test_key");
        params.addArgument("messageBody", "test_body");
        params.addArgument("producerName", "test_producerName");
        params.addArgument("producerGroup", "producerGroup");
        params.addArgument("timeout", "6000");
        params.addArgument("sendType", "oneWay");
        params.addArgument("delayTime", "100");

        return params;
    }
}

外掛準備

使用maven打包後,把jar包複製到apache-jmeter-5.4.3安裝目錄下\lib\ext。(因為把所有依賴包打入一個包失敗了,下圖是一個個在maven本地複製過來的)

Jmeter使用

jmeter重啟後,應該在取樣器中能看見java請求選項

主介面如下圖

執行成功如下圖

檢視rockermq的訊息皮膚,驗證成功

如果傳送失敗了,可以新增列印,在Jmeter的啟動命令控制檯進行除錯

相關文章