Jmeter实现dubbo接口压测案例

当前项目中重构了消息服务,需要对消息服务接口做性能压测,评估消息服务的性能情况

通过和开发对接,目前消息服务是通过dubbo接口对内提供服务,所以才有了这边文章的记录

最初的压测这个dubbo接口有三种思路:

1.第一种就是基于业务,比如注册业务,注册成功后,会发送短信消息到用户手机,通过业务调用消息服务,最容易实现,但是业务瓶颈最大导致测试结果不准

2.第二种是通过将dubbo接口上面做一层包装,提供一个http接口访问dubbo接口,需要提供二次开发,需要时间,而且高并发下,需要部署在tomcat容器内部

3.就是直接压测dubbo接口,这种测试的结果最准确,目前有开源的jmeter plguin sampler插件使用

下面讲解怎么使用jmeter-plugins-dubbo做接口测试

 

第一步:

源码下载:https://github.com/dubbo/jmeter-plugins-dubbo

https://github.com/ningyu1/jmeter-plugins-dubbo/tree/master/dist   jar下载地址

Jmeter实现dubbo接口压测案例_第1张图片

注意:

jmeter-plugins-dubbo使用

下载提供2种版本:

A. 第一种版本是jmeter-plugins-dubbo-1.3.8-jar-with-dependencies.jar类似带有with-dependencies的jar是包含一些基础包,建议下载这个

B. 第二种是不带依赖包的版本,例如jmeter-plugins-dubbo-1.3.8-SNAPSHOT.jar。然后获取以下依赖包,将它们放到jmeter安装目录下的lib/ext。如果是项目中使用报错,或者dubbo版本不是2.X版本的,建议下载这个

gson-2.8.2.jar

dubbo-2.8.4.jar  

javassist-3.21.0-GA.jar

jline-0.9.94.jar

log4j-over-slf4j-1.7.5.jar

netty-3.7.0.Final.jar

slf4j-api-1.7.5.jar

zkclient-0.2.jar

zookeeper-3.4.9.jar

 

第二步:

将下载的https://raw.githubusercontent.com/ningyu1/jmeter-plugins-dubbo/master/dist/jmeter-plugins-dubbo-1.3.8.jar

放在jar文件JMETER_HOME/lib/ext目录下

Jmeter实现dubbo接口压测案例_第2张图片

然后启动Jmeter

Jmeter实现dubbo接口压测案例_第3张图片

添加Dubbo Sampler配置如下

Jmeter实现dubbo接口压测案例_第4张图片

直接调用后,报错如下:

2019-01-17 14:22:49,051 ERROR i.g.n.j.p.d.s.DubboSample: RpcException:

com.alibaba.dubbo.rpc.RpcException: Failfast invoke providers dubbo://172.20.20.115:6001/com.neo.xnol.uaccount.facade.UserPersonQueryFacade?accepts=1024&accesslog=true&anyhost=true&application=DubboSample&async=false&charset=UTF-8&check=false&cluster=failfast&connections=100&default.cluster=failfast&default.delay=-1&default.loadbalance=leastactive&default.timeout=30000&default.version=2.0.0&delay=-1&dubbo=1.2.1-SNAPSHOT&generic=true&interface=com.neo.xnol.uaccount.facade.UserPersonQueryFacade&loadbalance=leastactive&methods=isPaymentPwdExist,getByMobile,getIdListByBirthday,isRealNameAuthByUserName,isRealNameAuth,isMobileExist,getTotalRegisteCount,getUserIdByRegisteTime,getByUserNameOrMobileOrEmail,isUserNameExist,getById,getByUserNameList,getUserForDistributed,getByIdCardNo,existElectronicSign,getByUserName,getByUserIdList,getUserByBeginIdAndCount,getByIdOrUserNameOrMobileOrEmail,getByEmail,getByUserNo,checkUserExist,isEmailExist,countUserRegister,getUserWithIDCardDistributed,getByUserNameOrMobile,isIdCardNoExist,getListByBeginIdAndCount&pid=87444&protocol=dubbo®ister.ip=172.20.17.65&remote.timestamp=1547636861571&retries=0&revision=2.130.0-SNAPSHOT&side=consumer&timeout=30000×tamp=1547706009472&version=2.0.0 LeastActiveLoadBalance select from all providers [com.alibaba.dubbo.registry.integration.RegistryDirectory$InvokerDelegate@611a4f9e] for service com.alibaba.dubbo.rpc.service.GenericService method $invoke on consumer 172.20.17.65 use dubbo version 1.3.8-jar-with-dependencies, but no luck to perform the invocation. Last error is: Failed to invoke remote method: $invoke, provider: dubbo://172.20.20.115:6001/com.neo.xnol.uaccount.facade.UserPersonQueryFacade?accepts=1024&accesslog=true&anyhost=true&application=DubboSample&async=false&charset=UTF-8&check=false&cluster=failfast&connections=100&default.cluster=failfast&default.delay=-1&default.loadbalance=leastactive&default.timeout=30000&default.version=2.0.0&delay=-1&dubbo=1.2.1-SNAPSHOT&generic=true&interface=com.neo.xnol.uaccount.facade.UserPersonQueryFacade&loadbalance=leastactive&methods=isPaymentPwdExist,getByMobile,getIdListByBirthday,isRealNameAuthByUserName,isRealNameAuth,isMobileExist,getTotalRegisteCount,getUserIdByRegisteTime,getByUserNameOrMobileOrEmail,isUserNameExist,getById,getByUserNameList,getUserForDistributed,getByIdCardNo,existElectronicSign,getByUserName,getByUserIdList,getUserByBeginIdAndCount,getByIdOrUserNameOrMobileOrEmail,getByEmail,getByUserNo,checkUserExist,isEmailExist,countUserRegister,getUserWithIDCardDistributed,getByUserNameOrMobile,isIdCardNoExist,getListByBeginIdAndCount&pid=87444&protocol=dubbo®ister.ip=172.20.17.65&remote.timestamp=1547636861571&retries=0&revision=2.130.0-SNAPSHOT&side=consumer&timeout=30000×tamp=1547706009472&version=2.0.0, cause: ooh.bravo.zodiac.rpc.RpcException: Failed to invoke remote proxy method $invoke to registry://s1.af88.com.cn:2181/ooh.bravo.zodiac.registry.RegistryService?application=User_RPC_Server&backup=s2.af88.com.cn:2181,s3.af88.com.cn:2181&dubbo=1.2.1-SNAPSHOT&export=dubbo://172.20.20.115:6001/com.neo.xnol.uaccount.facade.UserPersonQueryFacade?accepts=1024&accesslog=true&anyhost=true&application=User_RPC_Server&charset=UTF-8&default.cluster=failfast&default.delay=-1&default.loadbalance=leastactive&default.timeout=30000&default.version=2.0.0&delay=-1&dubbo=1.2.1-SNAPSHOT&interface=com.neo.xnol.uaccount.facade.UserPersonQueryFacade&methods=isPaymentPwdExist,getByMobile,getIdListByBirthday,isRealNameAuthByUserName,isRealNameAuth,isMobileExist,getTotalRegisteCount,getUserIdByRegisteTime,getByUserNameOrMobileOrEmail,isUserNameExist,getById,getByUserNameList,getUserForDistributed,getByIdCardNo,existElectronicSign,getByUserName,getByUserIdList,getUserByBeginIdAndCount,getByIdOrUserNameOrMobileOrEmail,getByEmail,getByUserNo,checkUserExist,isEmailExist,countUserRegister,getUserWithIDCardDistributed,getByUserNameOrMobile,isIdCardNoExist,getListByBeginIdAndCount&monitor=dubbo://s1.af88.com.cn:2181/ooh.bravo.zodiac.registry.RegistryService?application=User_RPC_Server&backup=s2.af88.com.cn:2181,s3.af88.com.cn:2181&dubbo=1.2.1-SNAPSHOT&file=/data/dubbo/cache/user_app_remoting.cache&pid=56&protocol=registry&refer=dubbo=1.2.1-SNAPSHOT&interface=ooh.bravo.zodiac.monitor.MonitorService&pid=56×tamp=1547636861608®istry=zookeeper×tamp=1547636861571&version=0.0.1&pid=56&revision=2.130.0-SNAPSHOT&side=provider×tamp=1547636861571&file=/data/dubbo/cache/user_app_remoting.cache&pid=56®istry=zookeeper×tamp=1547636861571&version=0.0.1, cause: Not found method "$invoke" in class com.neo.xnol.uaccount.facade.UserPersonQueryFacadeImpl.

ooh.bravo.zodiac.rpc.RpcException: Failed to invoke remote proxy method $invoke to registry://s1.af88.com.cn:2181/ooh.bravo.zodiac.registry.RegistryService?application=User_RPC_Server&backup=s2.af88.com.cn:2181,s3.af88.com.cn:2181&dubbo=1.2.1-SNAPSHOT&export=dubbo://172.20.20.115:6001/com.neo.xnol.uaccount.facade.UserPersonQueryFacade?accepts=1024&accesslog=true&anyhost=true&application=User_RPC_Server&charset=UTF-8&default.cluster=failfast&default.delay=-1&default.loadbalance=leastactive&default.timeout=30000&default.version=2.0.0&delay=-1&dubbo=1.2.1-SNAPSHOT&interface=com.neo.xnol.uaccount.facade.UserPersonQueryFacade&methods=isPaymentPwdExist,getByMobile,getIdListByBirthday,isRealNameAuthByUserName,isRealNameAuth,isMobileExist,getTotalRegisteCount,getUserIdByRegisteTime,getByUserNameOrMobileOrEmail,isUserNameExist,getById,getByUserNameList,getUserForDistributed,getByIdCardNo,existElectronicSign,getByUserName,getByUserIdList,getUserByBeginIdAndCount,getByIdOrUserNameOrMobileOrEmail,getByEmail,getByUserNo,checkUserExist,isEmailExist,countUserRegister,getUserWithIDCardDistributed,getByUserNameOrMobile,isIdCardNoExist,getListByBeginIdAndCount&monitor=dubbo://s1.af88.com.cn:2181/ooh.bravo.zodiac.registry.RegistryService?application=User_RPC_Server&backup=s2.af88.com.cn:2181,s3.af88.com.cn:2181&dubbo=1.2.1-SNAPSHOT&file=/data/dubbo/cache/user_app_remoting.cache&pid=56&protocol=registry&refer=dubbo=1.2.1-SNAPSHOT&interface=ooh.bravo.zodiac.monitor.MonitorService&pid=56×tamp=1547636861608®istry=zookeeper×tamp=1547636861571&version=0.0.1&pid=56&revision=2.130.0-SNAPSHOT&side=provider×tamp=1547636861571&file=/data/dubbo/cache/user_app_remoting.cache&pid=56®istry=zookeeper×tamp=1547636861571&version=0.0.1, cause: Not found method "$invoke" in class com.neo.xnol.uaccount.facade.UserPersonQueryFacadeImpl.

at ooh.bravo.zodiac.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:59)

at ooh.bravo.zodiac.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:35)

at ooh.bravo.zodiac.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:35)

at ooh.bravo.zodiac.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:78)

at ooh.bravo.zodiac.monitor.support.MonitorFilter.invoke(MonitorFilter.java:40)

at ooh.bravo.zodiac.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:78)

at ooh.bravo.zodiac.rpc.filter.ContextFilter.invoke(ContextFilter.java:36)

at ooh.bravo.zodiac.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:78)

at ooh.bravo.zodiac.rpc.filter.DynamicLinkTrackingFilter.invoke(DynamicLinkTrackingFilter.java:57)

at ooh.bravo.zodiac.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:78)

 

是不是看到这里已经懵逼了啊。哈哈,既然出现了问题,那么就要学着分析:首先查看这个接口的实际调用的参数咋样:

通过dubbo默认提供的invoke指令查看:

Jmeter实现dubbo接口压测案例_第5张图片

 

Jmeter实现dubbo接口压测案例_第6张图片

方法也存在,那么继续查看这个方法的dubbo调用参数

ls -l

url转码后:

com.neo.xnol.uaccount.facade.UserPersonQueryFacade -> dubbo://172.20.20.115:6001/com.neo.xnol.uaccount.facade.UserPersonQueryFacade?accepts=1024&accesslog=true&anyhost=true&application=User_RPC_Server&charset=UTF-8&default.cluster=failfast&default.delay=-1&default.loadbalance=leastactive&default.timeout=30000&default.version=2.0.0&delay=-1&dubbo=1.2.1-SNAPSHOT&interface=com.neo.xnol.uaccount.facade.UserPersonQueryFacade&methods=isPaymentPwdExist,getByMobile,getIdListByBirthday,isRealNameAuthByUserName,isRealNameAuth,isMobileExist,getTotalRegisteCount,getUserIdByRegisteTime,getByUserNameOrMobileOrEmail,isUserNameExist,getById,getByUserNameList,getUserForDistributed,getByIdCardNo,existElectronicSign,getByUserName,getByUserIdList,getUserByBeginIdAndCount,getByIdOrUserNameOrMobileOrEmail,getByEmail,getByUserNo,checkUserExist,isEmailExist,countUserRegister,getUserWithIDCardDistributed,getByUserNameOrMobile,isIdCardNoExist,getListByBeginIdAndCount&monitor=dubbo://s1.af88.com.cn:2181/ooh.bravo.zodiac.registry.RegistryService?application=User_RPC_Server&backup=s2.af88.com.cn:2181,s3.af88.com.cn:2181&dubbo=1.2.1-SNAPSHOT&file=/data/dubbo/cache/user_app_remoting.cache&pid=56&protocol=registry&refer=dubbo=1.2.1-SNAPSHOT&interface=ooh.bravo.zodiac.monitor.MonitorService&pid=56×tamp=1547636861608®istry=zookeeper×tamp=1547636861571&version=0.0.1&pid=56&revision=2.130.0-SNAPSHOT&side=provider×tamp=1547636861571

 

通过查看和对比,参数也没错,然后尝试直连,还是报错:

Jmeter实现dubbo接口压测案例_第7张图片

通过下载这个插件的源码和项目中的dubbo分析以及报错日志分析发现插件用的是dubbo的泛化调用, 而报错日志显示的是获取不到泛化对象 ,

通过对比发现是因为项目中的dubbo版本是用的2.5.4,但是在源码的基础上做了阉割,去掉了一部分功能,刚好去掉了jmeter插件使用到的dubbo的泛化调用特性,导致一直报错

通过修改原始插件,通过重写插件调用dubbo接口的调用方式后问题解决,如果外面的其他引入完整的dubbo源码项目,基本不会遇见这种问题

重新运行结果:

Jmeter实现dubbo接口压测案例_第8张图片

Jmeter实现dubbo接口压测案例_第9张图片

这个接口实现的业务

 

通过zk连接:

Jmeter实现dubbo接口压测案例_第10张图片

 

问题解决了

 

那么再来看这个消息服务的案例:

Jmeter实现dubbo接口压测案例_第11张图片

Jmeter实现dubbo接口压测案例_第12张图片

 

zk的方式:

Jmeter实现dubbo接口压测案例_第13张图片

 

 

 

 

难点就是这个参数类型怎么获取呢
Jmeter实现dubbo接口压测案例_第14张图片

简单吧,哈哈

其他案例:

Jmeter实现dubbo接口压测案例_第15张图片

Jmeter实现dubbo接口压测案例_第16张图片

Jmeter实现dubbo接口压测案例_第17张图片

 

Jmeter实现dubbo接口压测案例_第18张图片

 

常用参数类型汇总

Jmeter实现dubbo接口压测案例_第19张图片

 

首先拿到dubbo接口后,需要判断dubbo接口是否可用,我们怎么调试呢?可以通过dubbo默认提供的invoke指令调用,案例实战:

dubbo服务发布之后,我们可以利用telnet命令进行调试、管理。
Dubbo2.0.5以上版本服务提供端口支持telnet命令,下面我以通过实例抛砖引玉一下:

1.连接服务

测试对应IP和端口下的dubbo服务是否连通,cmd命令如下

telnet localhost 20880

正常情况下,进入telnet窗口,键入回车进入dubbo命令模式。

2.查看服务列表

查看服务ls

查看服务中的接口

ls

(list services and methods)

ls

显示服务列表。

ls -l

显示服务详细信息列表。

ls XxxService

显示服务的方法列表。

ls -l XxxService

显示服务的方法详细信息列表。

3.调用服务接口

调用接口时,以JSON格式传入参数(这点很方便 :-D),然后打印返回值和所用时间。

invoke

invoke XxxService.xxxMethod({"prop": "value"})

调用服务的方法。

invoke xxxMethod({"prop": "value"})

调用服务的方法(自动查找包含此方法的服务)。

4.查看服务状态 

查看服务调用次数,不过比较奇怪的是,我刚才已经调用过一次queryDemoPageList了,而这里显示的为0(貌似不太准,有待进一步了解)

Jmeter实现dubbo接口压测案例_第20张图片

count

count XxxService

统计1次服务任意方法的调用情况。

count XxxService 10

统计10次服务任意方法的调用情况。

count XxxService xxxMethod

统计1次服务方法的调用情况。

count XxxService xxxMethod 10

统计10次服务方法的调用情况。

status

status

显示汇总状态,该状态将汇总所有资源的状态,当全部OK时则显示OK,只要有一个ERROR则显示ERROR,只要有一个WARN则显示WARN。

status -l

显示状态列表。

 

比如,当前有个接口,获取当前系统的注册用户数的dubbo接口,我们可以先通过invoke指令验证

telnet 172.20.20.115 6001  这里说明,172.20.20.115是我们的dubbo服务地址,6001是user服务的端口

Jmeter实现dubbo接口压测案例_第21张图片

Jmeter实现dubbo接口压测案例_第22张图片

接口调用结果

 

参考:

https://blog.csdn.net/cyjs1988/article/details/84258046

你可能感兴趣的:(Jmeter)