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相关(打包需要),建议就使用如下配置,不要做其他更改,使用其他配置,可能导致产生一些无法预知的问题。
org.apache.maven.plugins
maven-shade-plugin
1.4
package
shade
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
META-INF/spring.handlers
com.fxc.rpc.impl.member.MemberProvider
META-INF/spring.schemas
3、 Dubbo配置
1) 编写dubbo消费端配置文件
Resources文件夹下面新建dubbo-client.xml
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 list = new ArrayList();
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 list = new ArrayList();
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运行用例,分析报告此文不做详解