脚本压测的前提:
- 已经安装好JMETER,并且会使用
- 有编好了的Java可执行jar的脚本
安装:去官网下载压缩文件,解压到本地文件夹即可,百度有很多
使用:这里可参考JMETER之文件传输的使用参考
注: 脚本压测是根据业务的压测不同来进行的
压测需求如下
第一次请求结束后会在请求头里获得一个SSION_ID
后面的三次请求交易的请求头需要这个SSION_ID;
注:第一次请求的url和后三次请求不同,但是后三次请求的url是一样的
脚本的Java代码
HttpURLConnectionDemos类
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类
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中进行执行的代码
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类
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了