dubbo服务集成Jmeter(二)的文章中,也是通过java代码编写集成到Jmeter中,使用jmeter对其dubbo服务接口进行访问。但是最终压测时发现,这种方式并不能实现压测,因为java代码编写的逻辑是通过telnet的方式进行访问的,在压测过程中使用telnet方式进行并发访问,访问时无异于一直打开命令行小窗口,最终本地机器倒成了压测的瓶颈。最终结果随着并发加大,接口的吞吐量并没有增加。所以此次针对dubbo服务压测编写脚本,实现能够压测到dubbo服务瓶颈的脚本。
dubbo压测,网上有针对jmeter压测dubbo服务专有的插件jar包,通过将jar包导入到jmeter安装路径的/lib/ext目录下,然后打开jmeter添加dubbo的取样器实现压测,插件jar包的名字:
jmeter-plugins-dubbo-{version}-jar-with-dependencies.jar。
我通过jmeter导入插件jar的种方式进行访问dubbo服务接口一直调试不通。后来自己通过编写java代码请求dubbo服务,并最终集成到jmeter中实现压测dubbo服务。
首先看一下java代码请求dubbo服务的代码:
以上截图中则是通过java代码请求dubbo服务并返回结果的代码调试案例。之后我们通过集成jmeter的类,实现将此代码集成打成jar包,并上传到jmeter中。用以压测。
通过代码集成Jmeter:
首先需要搭建java工程,可以搭建一个简单的project工程即可。
然后倒入相关包:如下
第一步:先将请求dubbo服务时,配置服务的代码实现单例,压测时只连接一次zookeeper。
package com.juzi.cs.util;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.utils.ReferenceConfigCache;
import com.alibaba.dubbo.rpc.service.GenericService;
/**
* @ClassName GetReferenceConfig
* @Description TODO
* @Author wangxiaowu
* @Date 2022/1/20 17:18
* @Version 1.0
*/
public class GetReferenceConfig {
private static GetReferenceConfig getReferenceConfig = null;
private static ReferenceConfig<GenericService> referenceConfig = null;
private static ReferenceConfigCache cache = null;
private static GenericService genericService = null;
private GetReferenceConfig(){}
public synchronized static GetReferenceConfig getInstance(){
if(getReferenceConfig == null){
getReferenceConfig = new GetReferenceConfig();
referenceConfig = new ReferenceConfig();
referenceConfig.setApplication(new ApplicationConfig("***-provider-test"));
referenceConfig.setRegistry(new RegistryConfig("zookeeper://test-zk.****.com:2181"));
referenceConfig.setGeneric(true);
referenceConfig.setTimeout(20000);
referenceConfig.setInterface("com.***.trial.dubbo.***RemoteService");
referenceConfig.setGroup("***-test");
cache = ReferenceConfigCache.getCache();
genericService = (GenericService) cache.get(referenceConfig);
System.out.println("新注册了zookeeper......");
}
return getReferenceConfig;
}
public GenericService getGenericService(){
return genericService;
}
}
第二步:集成jmeter的实现类,用于导入jmeter的jar包时,可以通过java请求取样器选择:
package com.juzi.jmeter;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.alibaba.fastjson.JSONObject;
import com.juzi.bean.TrialReq;
import com.juzi.cs.util.GetReferenceConfig;
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;
/**
* @ClassName Dubbo_Hx_Api
* @Description TODO
* @Author wangxiaowu
* @Date 2022/1/20 17:30
* @Version 1.0
*/
public class Dubbo_Hx_Api extends AbstractJavaSamplerClient {
private GetReferenceConfig getReferenceConfig;
private GenericService genericService;
private String questParam = "{\"application\":\"cheng\"}";
/**
* 用来自定义参数的方法,Jmeter中的java请求取样器中的入参定义方法
* 每个线程测试前执行一次,做一些初始化工作
* @return
*/
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("questParam", questParam);
return params;
}
/**
* 获取参数的方法,用来获取Jmeter中传入的参数
* @param context
*/
@Override
public void setupTest(JavaSamplerContext context) {
getReferenceConfig = GetReferenceConfig.getInstance();
genericService = getReferenceConfig.getGenericService();
}
@Override
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
//new一个SampleResult对象,用来实现计时、结果回写等操作。
SampleResult sr=new SampleResult();
try {
//请求开始计时
sr.sampleStart();
// 此处是方法中传入的实体类。可以开发代码获得,第一种方式。也可以通过第二种方式
TrialReq trialReq = JSONObject.parseObject(questParam,TrialReq.class);
Object result = genericService.$invoke("trial", new String[]{"com.***.trial.dubbo.req.***"}, new Object[]{trialReq});
// 也可以通过jsonObject将json参数转换为Object,第二种方式
// Object parse = JSONObject.parse(requestParam);
// Object result = genericService.$invoke("trial", new String[]{"com.***.trial.dubbo.req.***"}, new Object[]{parse});
// 设置显示数据
sr.setResponseData(JSONObject.toJSONString(result),null);
//设置请求的结束状态。
sr.setSuccessful(true);
}catch (Exception e){
sr.setResponseData("fail msg:"+e.getMessage(),sr.TEXT);
sr.setSuccessful(false);
}finally {
//请求结束计时。
sr.sampleEnd();
}
return sr;
}
@Override
public void teardownTest(JavaSamplerContext context) {
super.teardownTest(context);
// System.exit(0);
}
}
第三步:通过build的方式将工程打成jar包:
然后打开jmeter进行压测:
打开jmeter添加线程组,并添加一个java请求取样器:
添加成功后,我们可以看到我们继承的访问dubbo服务的请求选择:
然后发送一次请求,查看是否可以访问通:
然后设置并发进行压测即可:压测结果
至此,Java代码集成Jmeter压测dubbo服务脚本完毕。
以上脚本单单为了调试,写的是一种逻辑及实现重点。原则上dubbo接口路径、方法名、zookeeper地址、参数等等都可以写成jmeter的java取样器传参的形式获取到,然后进行压测,更为灵活些。