JMETER脚本压测
- 压测需求如下
- 脚本的Java代码
-
- 将写好的代码进行导出(eclipse)
- 在安装jmeter下的bin文件夹下打开jmeter.bat的启动文件
脚本压测的前提:
- 已经安装好JMETER,并且会使用
- 有编好了的Java可执行jar的脚本
安装:去官网下载压缩文件,解压到本地文件夹即可,百度有很多
使用:这里可参考JMETER之文件传输的使用参考
注: 脚本压测是根据业务的压测不同来进行的
压测需求如下
第一次请求结束后会在请求头里获得一个SSION_ID
后面的三次请求交易的请求头需要这个SSION_ID;
注:第一次请求的url和后三次请求不同,但是后三次请求的url是一样的
脚本的Java代码
HttpURLConnectionDemos类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Map; public class HttpURLConnectionDemos {<!-- --> public String doPost(Map<String, Object> map) {<!-- --> OutputStream os = null; BufferedReader in = null; HttpURLConnection conn = null; URL url = null; try {<!-- --> // 判断交易的url,第一个交易执行path1,第2,3,4交易执行path if((Boolean)map.get("judge") == true) {<!-- --> url = new URL((String) map.get("path1")); } else {<!-- --> url = new URL((String) map.get("path")); } conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("X-ABX-ModuleName", ((String)map.get("modulName"))); conn.setRequestProperty("X-ABX-SessionID", (String) map.get("sessionID")); conn.setRequestProperty("X-ABX-TradeName","trade%2F%E5%AE%A2%E6%88%B7%E4%BF%A1%E6%81%AF%E7%BB%B4%E6%8A%A4"); conn.setRequestProperty("X-ABX-TradeTitle", "%E5%AE%A2%E6%88%B7%E4%BF%A1%E6%81%AF%E7%BB%B4%E6%8A%A4"); conn.setRequestProperty("X-ABX-StepKey", URLEncoder.encode(((String) map.get("StepKey")), "UTF-8")); conn.setRequestProperty("X-ABX-OID", (String) map.get("OID"));// 新增 // conn.setRequestProperty("X-ABX-OID", "%7B%0A%09%22A%22%3A%22"+map.get("OID")+"%22%0A%7D"); conn.setRequestProperty("X-ABX-MemberOIDS", "%7B%22"+map.get("OID")+"%22%3A%22A%22%7D"); // conn.setRequestProperty("X-ABX-MemberOIDS", "%7B%22newId11%22%3A%22A%22%7D"); conn.connect(); os = conn.getOutputStream(); StringBuffer strbuffer = new StringBuffer(); try( // 使用语法糖,使用语法糖可以 使代码简洁可观,即只需写try即可,不用加cath和fianlly // FileInputStream fis = new FileInputStream("/home/abs/data/" + map.get("url")); FileInputStream fis = new FileInputStream("F:/data/" + map.get("url")); InputStreamReader inputStreamReader = new InputStreamReader(fis, "UTF-8"); BufferedReader inBR = new BufferedReader(inputStreamReader) ) {<!-- --> String str = null; while ((str = inBR.readLine()) != null) {<!-- --> strbuffer.append(str); } inBR.close(); } String jsonString = strbuffer.toString(); os.write(jsonString.getBytes(StandardCharsets.UTF_8)); os.flush(); conn.getResponseMessage(); } catch (Exception e) {<!-- --> e.printStackTrace(); } finally {<!-- --> try {<!-- --> if (os != null) {<!-- --> os.close(); } if (in != null) {<!-- --> in.close(); conn.disconnect(); } } catch (IOException ioe) {<!-- --> ioe.printStackTrace(); } } return ""; } } |
Websockets类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; public class WebSockets extends WebSocketClient {<!-- --> private AtomicInteger atomicInteger = new AtomicInteger(2); Map<String, Object> map1 = new HashMap<String, Object>(); CountDownLatch countDownLatch; public WebSockets(String uri) throws Exception {<!-- --> this(new URI(uri)); } public WebSockets(URI serverUri) {<!-- --> super(serverUri); } public WebSockets(String string, CountDownLatch countDownLatch, Map<String, Object> map1) throws URISyntaxException {<!-- --> this(new URI(string)); this.map1 = map1; this.countDownLatch = countDownLatch; } @Override public void onOpen(ServerHandshake serverHandshake) {<!-- --> } @Override public void onMessage(String message) {<!-- --> try {<!-- --> Map<String, Object> map = parses(message); if (map.containsKey("end")) {<!-- --> //在确定推送的消息中包含end时进行场景判断,再判断end为false继续执行,为true则结束 Map<String, Object> ack = new HashMap<>(); ack.put("msgId", map.get("msgId")); ack.put("type", "ack"); this.send(ack); if (((Boolean) map.get("end") == false) & ((Boolean) map.get("msgType") == false)) {<!-- --> System.out.println("==" + atomicInteger + message); new Thread(() -> {<!-- --> map.put("url", atomicInteger.getAndIncrement()+".txt"); map.put("path", map1.get("path")); map.put("OID", map1.get("OID")); map.put("judge", false); new HttpURLConnectionDemos().doPost(map); countDownLatch.countDown(); }).start(); } else {<!-- --> System.out.println("==" + atomicInteger + message); countDownLatch.countDown(); close(); } } } catch (UnsupportedEncodingException e) {<!-- --> e.printStackTrace(); } } @Override public void onClose(int i, String s, boolean b) {<!-- --> System.out.println("close"); } @Override public void onError(Exception e) {<!-- --> } public void createWebSocket() throws Exception {<!-- --> if (!this.isClosed() || !this.isClosing()) {<!-- --> connectBlocking(); } } public void sendData(Map<String, Object> data) {<!-- --> if (this.isOpen()) {<!-- --> send(JSON.toJSONString(data)); } } public void send(Map<String, Object> sendData) {<!-- --> if (this.isOpen()) {<!-- --> send(JSON.toJSONString(sendData)); } } @SuppressWarnings("unchecked") private Map<String, Object> parses(String string) throws UnsupportedEncodingException {<!-- --> Map<String, Object> map = (Map<String, Object>) JSONObject.parseObject(string); Map<String, Object> reqMap = new HashMap<>(); // 线程刚开启时第一次执行 if (map.containsKey("code")) {<!-- --> // Map<String, Object> FMap = new HashMap<>(); reqMap.put("StepKey", ""); reqMap.put("sessionID", ""); reqMap.put("msgId", ""); return reqMap; // 线程执行之后的四次请求 } else {<!-- --> // Map<String, Object> reqMap = new HashMap<>(); String StepKey = (String) ((Map<String, Object>) ((Map<String, Object>) map.get("data")).get("meta")) .get("stepKey"); String sessionID = (String) ((Map<String, Object>) ((Map<String, Object>) map.get("data")).get("meta")) .get("sessionID"); Boolean end = (Boolean) ((Map<String, Object>) ((Map<String, Object>) map.get("data")).get("meta")) .get("end"); String msgId = (String) map.get("msgId"); Boolean msgType = (Boolean) map.containsKey("msgType"); reqMap.put("StepKey", StepKey); reqMap.put("sessionID", sessionID); reqMap.put("end", end); reqMap.put("msgId", msgId); reqMap.put("msgType", msgType); return reqMap; } } } |
JmeterClient类 : 这个类主要是写能在Jmeter中进行执行的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.CountDownLatch; 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; public class JmeterClient extends AbstractJavaSamplerClient {<!-- --> private String OID; private String tradeName; private String tradeTitle; private String sessionID; private String stepKey; private String path1; private String path; private String modulName; private CountDownLatch countDownLatch = new CountDownLatch(1); private Boolean judge = false; public Arguments getDefaultParameters() {<!-- --> Arguments args = new Arguments(); // args.addArgument("path", "http://49.233.250.34/wangyang/moduleb-aase/aase/index"); args.addArgument("path1", "http://49.233.250.34:80/wangyang/moduleb-aase/aase/openTrade"); args.addArgument("path", "http://49.233.250.34:80/wangyang/moduleb-aase/aase/execTrade"); args.addArgument("Content-Type", "application/json"); args.addArgument("X-ABX-ModuleName", "ModuleB"); args.addArgument("X-ABX-TradeName", "trade%2F%E5%AE%A2%E6%88%B7%E4%BF%A1%E6%81%AF%E7%BB%B4%E6%8A%A4"); args.addArgument("X-ABX-TradeTitle", "%E5%AE%A2%E6%88%B7%E4%BF%A1%E6%81%AF%E7%BB%B4%E6%8A%A4"); args.addArgument("X-ABX-StepKey", ""); args.addArgument("X-ABX-SessionID", ""); return args; } @Override public void setupTest(JavaSamplerContext context) {<!-- --> String str = UUID.randomUUID().toString(); String tempString = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24); OID = tempString; path1 = context.getParameter("path1"); path = context.getParameter("path"); tradeName = context.getParameter("X-ABX-TradeName"); tradeTitle = context.getParameter("X-ABX-TradeTitle"); sessionID = context.getParameter("X-ABX-StepKey"); stepKey = context.getParameter("X-ABX-StepKey"); modulName = context.getParameter("X-ABX-ModuleName"); Map<String, Object> map = new HashMap<String, Object>(); map.put("OID", OID); map.put("tradeName", tradeName); map.put("tradeTitle", tradeTitle); map.put("StepKey", stepKey); map.put("path", path); map.put("sessionID", sessionID); map.put("modulName", modulName); WebSockets webSocket; try {<!-- --> webSocket = new WebSockets("ws://49.233.250.34/wangyang/message/message/websocket", countDownLatch,map); webSocket.createWebSocket(); Map<String, Object> initMessage = new HashMap<>(); Map<String, String> data = new HashMap<>(); initMessage.put("type", "init"); initMessage.put("id", OID); initMessage.put("data", data); webSocket.sendData(initMessage); } catch (URISyntaxException e) {<!-- --> e.printStackTrace(); } catch (Exception e) {<!-- --> e.printStackTrace(); } } /** * 每个线程执行多次,相当于loadrunner的Action()方法 (non-Javadoc) */ public SampleResult runTest(JavaSamplerContext arg0) {<!-- --> boolean if_success = true;// 测试结果标记位 SampleResult sr = new SampleResult(); // 为避免多线程问题,设置sr为局部变量 sr.setSampleLabel("java请求"); try {<!-- --> Map<String, Object> fMap = new HashMap<>(); fMap.put("StepKey", ""); fMap.put("sessionID", ""); fMap.put("OID", OID); fMap.put("path1", path1); fMap.put("modulName", modulName); fMap.put("url", "1.txt"); judge = true; fMap.put("judge", judge); sr.sampleStart(); // 开始发起第一次请求 new HttpURLConnectionDemos().doPost(fMap); // countDownLatch.countDown(); sr.setResponseData("响应结果", "utf-8"); // 第二个参数 为编码, 设置JMeter GUI "取样器结果" DataEncoding: utf-8 sr.setDataType(SampleResult.TEXT); // 设置JMeter GUI "取样器结果" Data type ("text"|"bin"|""):text sr.setResponseMessageOK(); // 设置JMeter GUI "取样器结果" Response message: OK sr.setResponseCodeOK(); // 设置JMeter GUI "取样器结果" Response code: 200 if_success = true; // countDownLatch.await(); } catch (Exception e) {<!-- --> if_success = false; // 请求失败 sr.setResponseCode("500"); // 设置JMeter GUI "取样器结果" Response code: 500 e.printStackTrace(); } finally {<!-- --> try {<!-- --> countDownLatch.await(); } catch (InterruptedException e) {<!-- --> // TODO Auto-generated catch block e.printStackTrace(); } sr.sampleEnd(); sr.setSuccessful(if_success); } return sr; } public void teardownTest() {<!-- --> } } |
TestJarClass类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; public class TestJarClass {<!-- --> public static void main(String[] args) {<!-- --> for (int i = 0; i < 1; i++) {<!-- --> Thread thread = new Thread(() -> {<!-- --> // lamda表达式 JmeterClient test = new JmeterClient(); Arguments arg0 = test.getDefaultParameters(); JavaSamplerContext argResult = new JavaSamplerContext(arg0); test.setupTest(argResult); test.runTest(argResult); }); thread.start(); } } } |
将写好的代码进行导出(eclipse)
第一步:
第二步:
第三步:将导出的jar文件放到安装jmeter的\apache-jmeter-5.3\lib\ext
例如我的:F:\Program Files\apache-jmeter-5.3\lib\ext
在安装jmeter下的bin文件夹下打开jmeter.bat的启动文件
看到此处下面的就OK了