[JMeter]壓力測試 Hessian Service
基本資料:
http://jmeter.apache.org/usermanual/index.html
參考文件:
http://sunqi.iteye.com/blog/807475
http://henry-tech-notes.blogspot.com/2006/10/testing-hessian-services-with-jmeter.html
依照參考文件即可組合 jmeter + eclipse + hessian 的壓力測試環境.
中間遇到的問題:
1. 加入新的Java 要求及實作之類別, 執行後Console 未報錯, 報表亦未顯示任何執行結果:
A: 先查找 %JMETER_HOME%\bin\jmeter.log
2011/12/19 19:11:41 ERROR - jmeter.threads.JMeterThread: Test failed! java.lang.NoClassDefFoundError: com/caucho/hessian/client/HessianProxyFactory
at HessianTest.setupTest(HessianTest.java:50)
at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:158)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:411)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:297)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.caucho.hessian.client.HessianProxyFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 5 more
原來是我的 ANT 少加了一個服務依賴的JAR檔 (如: XXXInterface.jar ).
2. 整合進eclipse時, 找不到 NewDriver.class 去執行:
A: 文章有差異, 應該在 %JMETER_HOME%\bin\ApacheJMeter.jar 而非 %JMETER_HOME%\lib\ApacheJMeter_core.jar
3. 除錯模式時找不到新增的Source code:
A: 在Debug configuration > Source 按下 [Add], 選擇 Workspace Folder, 再選擇專案中的source folder.
快速步驟提示:
1. 建立PT 專案
2. 將所需Library 加入build path :
ApacheJMeter_core.jar
ApacheJMeter_java.jar
hessian-3.0.13.jar
XXXInterface.jar
3. 撰寫Java Code
// 繼承 Java 要求
public class HessianTest extends AbstractJavaSamplerClient
// 實作預設參數
@Override
public Arguments getDefaultParameters()
// 初始化必要的物件: 如XXXService by HessianProxyFactory
@Override
public void setupTest(JavaSamplerContext context) {
// 實作測試案例
@Override
public SampleResult runTest(JavaSamplerContext arg0) {
4. 製作 ANT build.xml , 將專案編譯/包裝/佈署
4.1 需加相依的專案元件檔一併放作%JMETER_HOME%\lib\ext. ps.sample 如附錄1
4.2 此時已可以獨立執行%JMETER_HOME%\bin\jmeter.bat.
5. (option) 整合Eclipse
5.1 以ApacheJmeter.jar 中的org.apache.jmeter.NewDriver.class 為主程式
5.2 在Arguments:Tab 將Working directory 指到 %JMETER_HOME%\bin
5.3 在Classpath:Tab 將default classpath 移除, 然後只增加一個 %JMETER_HOME%\bin\ApacheJMeter.jar
5.4 在Source:Tab 將測試專案的source path 加入
====================
附錄1 – build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="SERVICE_PT" basedir=".">
<property file="build.properties"/>
<path id="classpath">
<fileset dir="${dir.lib}">
<include name="*.jar" />
</fileset>
</path>
<target name="main" >
<delete dir="${dir.temp}" />
<mkdir dir="${dir.temp}" />
<copy todir="${dir.temp}">
<fileset dir="${dir.src}" />
</copy>
<javac fork="true" debug="true" encoding="utf-8"
destdir="${dir.temp}" includes="**/*.java" includeantruntime="on">
<classpath refid="classpath"/>
<src path="${dir.temp}"/>
</javac>
<jar destfile="${dir.temp}/${file.jar.name}"
basedir="${dir.temp}"
includes="**/*.class"
excludes="**/*.jar" />
<copy file="${dir.temp}/${file.jar.name}" todir="${dir.jmeter.lib.ext}" />
<delete file="${dir.temp}" />
<echo message="${timestamp}" />
</target>
</project>
附錄2 - sample code
1: public class HessianTest extends AbstractJavaSamplerClient {
2:
3: public static String P_Service_URL="Service URL";
4: public static String P_User_Name="User Name";
5: public static String P_Password="Password";
6:
7:
8: ISearch search = null;
9:
10: @Override
11: public Arguments getDefaultParameters() {
12: Arguments args = new Arguments();
13: args.addArgument(P_Service_URL, "http://localhost:8080/Search");
14: args.addArgument(P_User_Name, "ok");
15: args.addArgument(P_Password, "ok");
16: return args;
17: }
18:
19: @Override
20: public void setupTest(JavaSamplerContext context) {
21: String url = context.getParameter(P_Service_URL);
22: String user = context.getParameter(P_User_Name);
23: String password = context.getParameter(P_Password);
24:
25: try{
26: HessianProxyFactory factory = new HessianProxyFactory();
27: factory.setUser(user);
28: factory.setPassword(password);
29: searchParty = (ISearch) factory.create(ISearch.class ,url);
30: }catch(Exception e){
31: e.printStackTrace();
32: throw new RuntimeException("Error getting hessian proxy", e);
33: }
34: }
35:
36:
37: @Override
38: public SampleResult runTest(JavaSamplerContext arg0) {
39: SampleResult result = generateSampleResult("Call Hessain Service");
40: result.sampleStart();
41: try{
42: RequestHeader requestHeader = setupRequestHeader();
43: ArrayList<RequestBody> requestBodys = setupRequestBody();
44:
45: int i=0;
46: int errCount=0;
47:
48: for (RequestBody requestBody : requestBodys) {
49: i++;
50: SampleResult subResult = generateSampleResult("test." + i);
51: result.addSubResult(subResult);
52:
53: subResult.sampleStart();
54: try{
55: ResponseMessage responseMessage = search.searchCustomer(requestHeader,requestBody);
56: byte[] responseData = resultMessageSerialize(responseMessage).getBytes();
57: successHandler(subResult, 0, responseData);
58: }catch(Throwable e){
59: errCount ++;
60: exceptionHandler(subResult, e);
61: }
62: subResult.sampleEnd();
63: }
64: successHandler(result, errCount, "".getBytes());
65: }catch (Exception e) {
66: exceptionHandler(result, e);
67: }
68: result.sampleEnd();
69: return result;
70: }
71:
72: private void successHandler(SampleResult result, int errCount, byte[] responseData){
73: boolean hadErr = errCount > 0;
74: if(hadErr){
75: result.setSuccessful(false);
76: result.setErrorCount(errCount);
77: result.setResponseMessage("Finish but had error.");
78: }else{
79: result.setSuccessful(true);
80: result.setResponseCodeOK();
81: result.setResponseMessage("Success");
82: }
83: result.setResponseData(responseData);
84: }
85:
86: private void exceptionHandler(SampleResult result, Throwable e){
87: result.setSuccessful(false);
88: result.setResponseMessage(e.getClass().getName() + " " + e.getLocalizedMessage());
89: result.setResponseData(exceptionSerialize(e).getBytes());
90: }
91:
92: private String exceptionSerialize(Throwable e){
93: StringWriter sw = new StringWriter();
94: e.printStackTrace(new PrintWriter(sw));
95: return sw.toString();
96: }
97: }