Jmeter 是什么?
Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。
为什么要进行二次插件开发
因为有时候自带的取样器无法满足我们的需求,我们需要自己定义就需要进行二次插件开发了,其实这个开发的流程也非常的简单,只需要实现其中几个接口就可以了。
例如Jmeter自带的TCP取样器的行尾(EOL字节值)只能设置的范围只能是[-128,127],判断行结束的byte值,如果你指定的值大于127或者小于-128,则会跳过EOL检测,这样TCP就无法自动断开连接直至超时判断失败。
所以我们需要进行自定义的TCP取样器。
二次开发的步骤
- 首先使用IDEA新建普通java项目
- 将
jmeter
的lib/ext
目录下的ApacheJMeter_core.jar
和ApacheJMeter_java.jar
两个jar包引入
- 新建一个类实现
JavaSamplerClient
接口:
- getDefaultParameters:设置默认参数
- setupTest:测试前做的事
- runTest:测试时主要做的事
- teardownTest:测试后做的事,一般不做设置
runTest
runTest就是主要的测试逻辑部分,在这个函数中,我们需要记录开始于结束的时间,设置测试的标签和结果以及response等等。
code
我这里主要实现的就是一个发送自定义的16进制TCP报文并检测一次回复的报文尾部转换之后是否为指定字符串。
[tag type=“default”]SocketTest[/tag]类,主要的取样器类:
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
| package top.xhofe;
import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; import org.apache.jmeter.samplers.SampleResult;
import java.io.InputStream; import java.io.OutputStream; import java.net.Socket;
public class SocketTest implements JavaSamplerClient { private SampleResult result; private String host; private int port; private String content; private String end; @Override public void setupTest(JavaSamplerContext javaSamplerContext) { result=new SampleResult(); host=javaSamplerContext.getParameter("host"); port=Integer.parseInt(javaSamplerContext.getParameter("port")); content=javaSamplerContext.getParameter("content"); end=javaSamplerContext.getParameter("end"); }
@Override public SampleResult runTest(JavaSamplerContext javaSamplerContext) { String threadName=Thread.currentThread().getName(); result.setSampleLabel(threadName); result.setSamplerData("TCP发送:"+host+":"+port+"数据:"+content); result.sampleStart(); try { Socket socket=new Socket(host,port); OutputStream out=socket.getOutputStream(); byte[] hexStrToByteArr = Utils.hexStrToByteArr(content); if (hexStrToByteArr==null){ throw new Exception("hexStrToByteArr error"); } out.write(hexStrToByteArr); InputStream in=socket.getInputStream(); byte[] buf=new byte[1024]; int len=in.read(buf); String response=Utils.bytesToHexString(buf,len); result.setResponseData(response,"UTF-8"); socket.close(); if (!response.endsWith(end)){ throw new Exception("response:"+response+"not ends with:"+end); } result.setSuccessful(true); }catch (Exception e){ result.setSuccessful(false); e.printStackTrace(); }finally { result.sampleEnd(); } return result; }
@Override public void teardownTest(JavaSamplerContext javaSamplerContext) {
}
@Override public Arguments getDefaultParameters() { Arguments params=new Arguments(); params.addArgument("host","tcp.xhofe.top"); params.addArgument("port","9999"); params.addArgument("end","FB") ; params.addArgument("content","fa120106009a6946401000010077036a65b4002202175e4c00002f5b00002f5b00002f5b09080908007d04dd0bc3000000000175d3f077ca01f9000c000f0055006401f9004d001907e707de04bc000007de04bc000050643201fb"); return params; } }
|
[tag type=“success”]Utils[/tag]工具类,用于转换字符串和十六进制的转换:
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
| package top.xhofe;
public class Utils { public static byte[] hexStrToByteArr(String hexString) { if (hexString==null||hexString.isEmpty()) { return null; }
hexString = hexString.replaceAll(" ", ""); int len = hexString.length(); int index = 0;
byte[] bytes = new byte[len / 2];
while (index < len) { String sub = hexString.substring(index, index + 2); bytes[index / 2] = (byte) Integer.parseInt(sub, 16); index += 2; } return bytes; }
public static String bytesToHexString(byte[] bArray,int len) { StringBuilder sb = new StringBuilder(len); String sTemp; for (int i = 0; i < len; i++) { sTemp = Integer.toHexString(0xFF & bArray[i]); if (sTemp.length() < 2) { sb.append(0); } sb.append(sTemp.toUpperCase()); } return sb.toString(); } }
|
- 将代码打包成Jar包(此处不赘述)
- 将打包好的Jar包放到jmeter根目录/lib/ext目录下
- Jmeter添加线程组->添加取样器-Java请求->选择自定义的类->设置参数/使用默认的参数
- OK,完成!
参考
五步教你如何去做jmeter接口java二次开发