jmeter之脚本压力测试—执行脚本—JMETER脚本压力测试完整代码

JMETER脚本压测

  • 压测需求如下
  • 脚本的Java代码
    • 将写好的代码进行导出(eclipse)
  • 在安装jmeter下的bin文件夹下打开jmeter.bat的启动文件


脚本压测的前提:

  1. 已经安装好JMETER,并且会使用
  2. 有编好了的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了
在这里插入图片描述