上期是使用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的啟動命令控制檯進行除錯