当前项目中重构了消息服务,需要对消息服务接口做性能压测,评估消息服务的性能情况
通过和开发对接,目前消息服务是通过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下载地址
注意:
下载提供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 Sampler配置如下
直接调用后,报错如下:
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指令查看:
方法也存在,那么继续查看这个方法的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
通过查看和对比,参数也没错,然后尝试直连,还是报错:
通过下载这个插件的源码和项目中的dubbo分析以及报错日志分析发现插件用的是dubbo的泛化调用, 而报错日志显示的是获取不到泛化对象 ,
通过对比发现是因为项目中的dubbo版本是用的2.5.4,但是在源码的基础上做了阉割,去掉了一部分功能,刚好去掉了jmeter插件使用到的dubbo的泛化调用特性,导致一直报错
通过修改原始插件,通过重写插件调用dubbo接口的调用方式后问题解决,如果外面的其他引入完整的dubbo源码项目,基本不会遇见这种问题
重新运行结果:
通过zk连接:
问题解决了
那么再来看这个消息服务的案例:
zk的方式:
简单吧,哈哈
其他案例:
常用参数类型汇总
首先拿到dubbo接口后,需要判断dubbo接口是否可用,我们怎么调试呢?可以通过dubbo默认提供的invoke指令调用,案例实战:
dubbo服务发布之后,我们可以利用telnet命令进行调试、管理。
Dubbo2.0.5以上版本服务提供端口支持telnet命令,下面我以通过实例抛砖引玉一下:
测试对应IP和端口下的dubbo服务是否连通,cmd命令如下
telnet localhost 20880
正常情况下,进入telnet窗口,键入回车进入dubbo命令模式。
查看服务ls
查看服务中的接口
(list services and methods)
ls
显示服务列表。
ls -l
显示服务详细信息列表。
ls XxxService
显示服务的方法列表。
ls -l XxxService
显示服务的方法详细信息列表。
调用接口时,以JSON格式传入参数(这点很方便 :-D),然后打印返回值和所用时间。
invoke XxxService.xxxMethod({"prop": "value"})
调用服务的方法。
invoke xxxMethod({"prop": "value"})
调用服务的方法(自动查找包含此方法的服务)。
查看服务调用次数,不过比较奇怪的是,我刚才已经调用过一次queryDemoPageList了,而这里显示的为0(貌似不太准,有待进一步了解)
count
count XxxService
统计1次服务任意方法的调用情况。
count XxxService 10
统计10次服务任意方法的调用情况。
count XxxService xxxMethod
统计1次服务方法的调用情况。
count XxxService xxxMethod 10
统计10次服务方法的调用情况。
status
显示汇总状态,该状态将汇总所有资源的状态,当全部OK时则显示OK,只要有一个ERROR则显示ERROR,只要有一个WARN则显示WARN。
status -l
显示状态列表。
比如,当前有个接口,获取当前系统的注册用户数的dubbo接口,我们可以先通过invoke指令验证
telnet 172.20.20.115 6001 这里说明,172.20.20.115是我们的dubbo服务地址,6001是user服务的端口
接口调用结果
参考:
https://blog.csdn.net/cyjs1988/article/details/84258046