Dubbo接口壓力測試
2017-03-30更新:忘記了之前有個問題沒有在blog裏面跟大家說,由於Dubbo工程師引入了Spring相關的jar包了,但是Jmeter默認也是自帶了spring-core-2.5.6.jar包的(在lib目錄下),所以當我們將測試jar放到jmeter對應目錄下,重啓jmeter的時候回報spring的jar包衝突,所以在利用就jmeter做Dubbo接口測試的時候,我們需要將Jmeter自帶的spring-core-2.5.6.jar包去掉。
一、簡介
1、 需要環境工具:
需要環境:Jdk1.7、Maven;
開發工具:intellij idea(也可自行選擇eclipse);
測試工具:Jmeter3.0;
2、 Dubbo接口壓力測試:
編寫dubbo接口測試代碼調用dubbo服務,利用jmeter運行測試代碼,進行壓力測試
3、 Jmeter測試java接口:http://jmeter.apache.org/api/org/apache/jmeter/protocol/java/sampler/AbstractJavaSamplerClient.html
4、 代碼下載地址:
二、編寫dubbo測試代碼
1、 新建dubbo接口測試工程(建議一個dubbo服務工程對應一個dubbo接口測試工程,這樣方便代碼的管理)
1) .打開file -> new-> Project -> maven -> next, 新建maven工程
2) .填寫groupId、artifactId、version
GroupId:項目組織唯一的標識符,實際對應JAVA的包的結構,是main目錄裏java的目錄結構。
ArtifactId:就是項目的唯一的標識符,實際對應項目的名稱,就是項目根目錄的名稱。
Version:版本號。
3) 填寫project name
2、 配置pom.xml文件,注意:maven一定要配置成你本地的
1) 配置需要測試的dubbo服務
2) 配置需要的一些工具jar包(dubbo工程會有,可參考父工程pom.xml文件)。篇幅所致,此處只截圖展示部分。
3) 配置Jmeter相關的jar包,使用的是ApacheJMeter_java,版本號此處使用2.13,可自行在jmeter官網查看版本號,根據需要配置。
4) 配置build相關(打包需要),建議就使用如下配置,不要做其他更改,使用其他配置,可能導致產生一些無法預知的問題。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.fxc.rpc.impl.member.MemberProvider</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3、 Dubbo配置
1) 編寫dubbo消費端配置文件
Resources文件夾下面新建dubbo-client.xml
<dubbo:registry > : dubbo服務註冊配置
<dubbo:application> : dubbo應用名稱
<dubbo:reference> : 生成遠程服務代理,可以像使用本地bean一樣使用遠程服務。
<dubbo:consumer> : 消費端的一些缺省配置。
2) Dubbo初始化工具類編寫DubboInit。
1) 新建util包,新建DubboInit類,代碼如下
package util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by wangdingjin on 2016/9/2.
*/
public class DubboInit {
private static DubboInit init = null;
private DubboInit(){}
private static ApplicationContext context;
public synchronized static DubboInit getInstance(){
if(init == null){
init = new DubboInit();
}
return init;
}
public static void initApplicationContext(){
context = new ClassPathXmlApplicationContext("classpath:/dubbo-client.xml");
if(context==null)
{
throw new IllegalArgumentException("Load dubbo-client.xml fail");
}
}
public Object getBean(String beanName) {
return context.getBean(beanName);
}
}
3) 編寫測試代碼(此處建議現行編寫Junit測試代碼,測試通過之後,再編寫jmeter所需的測試代碼)
1) 編寫junit測試代碼
在test/java中新建package:directRegisterInfoService(根據自己喜好命名即可,我的喜好是測試一個服務接口就新建一個包,因爲一個服務裏面有很多方法,我們測試這些方法的時候,會針對每一個方法寫一個測試類)
此處用例爲測試取號列表(queryTakeRegNo),新建TqueryTakeRegNo類,編寫測試代碼如下:
package directRegisterInfoService;
import com.saohuobang.web.platform.bjmedicalcard.po.DirectRegisterInfo;
import com.saohuobang.web.platform.bjmedicalcard.service.DirectRegisterInfoInf;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import util.DubboInit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Administrator on 2016/9/2.
*/
public class TqueryTakeRegNo {
/*
*定義DirectRegisterInfoInf的變量
*/
@Autowired
private DirectRegisterInfoInf directRegisterInfoInf;
/*
*初始化directRegisterInfoService服務
*/
@Before
public void setupTest() {
DubboInit init = DubboInit.getInstance();
init.initApplicationContext();
directRegisterInfoInf = (DirectRegisterInfoInf)init.getBean("directRegisterInfoService");
}
/*
*測試代碼
*/
@Test
public void runTest() {
List<DirectRegisterInfo> list = new ArrayList<DirectRegisterInfo>();
try {
Map map = new HashMap();
map.put("dateTime", new DateTime().toString("yyyy-MM-dd 00:00:00"));// TODO
// map.put("dateTime","2016-01-26 00:00:00");
map.put("hosCode", "T113411");
map.put("cardNo", "98000001004327");
list = directRegisterInfoInf.getTakeNoList(map);
System.out.println("\n\n\n\n================"+list.get(0).getDeptname() + "==================\n\n\n\n");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
System.out.println();
}
}
2) 啓用debug調試,確認junit測試是否通過。(此處不做詳解)
3) Junit測試通過之後,編寫jmeter需要的測試代碼。
Main/java新建directRegisterInfoService包,新建LqueryTakeRegNo測試類,該測試類需要extendsAbstractJavaSamplerClient,
主要實現setupTest():初始化操作
getDefaultParameters():設置默認的jmeter的Parameters
SetValues(JavaSamplerContextarg0):根據jmeter填寫的參數設置變量值
runTest(JavaSamplerContextjavaSamplerContext):運行測試代碼。teardownTest(JavaSamplerContext arg0):測試收尾操作。
用例代碼如下(供參考):
package directRegisterInfoService;
import com.saohuobang.web.platform.bjmedicalcard.po.DirectRegisterInfo;
import com.saohuobang.web.platform.bjmedicalcard.service.DirectRegisterInfoInf;
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;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import util.DubboInit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Administrator on 2016/9/2.
*/
public class LqueryTakeRegNo extends AbstractJavaSamplerClient {
//需要測試的接口
@Autowired
private DirectRegisterInfoInf directRegisterInfoInf;
private long start = 0;//記錄測試開始時間;
private long end = 0;//記錄測試結束時間;
private String hosCode = "T113411";
private String cardNo = "98000001004327";
//初始化操作
@Override
public void setupTest(JavaSamplerContext arg0) {
DubboInit init = DubboInit.getInstance();
init.initApplicationContext();
directRegisterInfoInf = (DirectRegisterInfoInf) init.getBean("directRegisterInfoService");
}
/**
*
* 設置默認值
*
* @return
*/
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("hosCode", hosCode);
params.addArgument("cardNo", cardNo);
return params;
}
/**
* 獲取jmeter輸入的參數值
*
* @return
*/
public void setValues(JavaSamplerContext arg0) {
hosCode = arg0.getParameter("hosCode",hosCode);
cardNo = arg0.getParameter("cardNo",cardNo);
}
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
SampleResult sr = new SampleResult();
setValues(javaSamplerContext);
sr.sampleStart();
start = System.currentTimeMillis();
try {
List<DirectRegisterInfo> list = new ArrayList<DirectRegisterInfo>();
Map map = new HashMap();
map.put("dateTime", new DateTime().toString("yyyy-MM-dd 00:00:00"));// TODO
// map.put("dateTime","2016-01-26 00:00:00");
map.put("hosCode", hosCode);
map.put("cardNo", cardNo);
list = directRegisterInfoInf.getTakeNoList(map);
if (list != null && list.size() != 0) {
sr.setSuccessful(true);
sr.setResponseData("醫院:" + list.get(0).getHospname(), null);
sr.setDataType(SampleResult.TEXT);
} else {
sr.setSuccessful(false);
getLogger().error("LqueryTakeRegNo response is null");
}
} catch (Exception e) {
getLogger().error("LqueryTakeRegNo response error : " + e.getMessage());
sr.setSuccessful(false);
} finally {
sr.sampleEnd();
}
return sr;
}
@Override
public void teardownTest(JavaSamplerContext arg0) {
end = System.currentTimeMillis();
getLogger().info(" cost time: " + (end - start) + "ms");
}
}
4) 生成jar包:
Idea右側->mavenproject->Lifecycle->package即可生成jar包(******service_dubbo_test-1.0-SNAPSHOT.jar)
Jar包位置如下:
三、Jmeter運行測試用例
1、 導入jar包
將******service_dubbo_test-1.0-SNAPSHOT.jar放到\apache-jmeter-3.0\lib\ext目錄下。
2、 編寫jmeter測試腳本
新建線程組->java請求(右鍵sampler選擇java請求);
新建查看結果樹(做性能測試的時候,選擇)、聚合報告等組件。
類名稱選擇我們之前編寫的測試類即可。
進行性能測試的時候,填寫線程數、啓動線程時間、循環次數等。
進行性能測試的時候,查看結果樹務必勾選僅顯示日誌錯誤。
後面Jmeter運行用例,分析報告此文不做詳解