zyanycall / stressTestPlatform

基于Jmeter实现的在线压测和管理Jmx的平台。
Apache License 2.0
623 stars 343 forks source link

调试模式的时候,自己写的java请求,引自己封装的jar,会报java.lang.ClassNotFoundException #47

Closed jinjunge closed 5 years ago

jinjunge commented 5 years ago

运行调试模式的时候 ,自己写的java请求,引自己封装的jar,会报java.lang.ClassNotFoundException,需要怎么处理?

zyanycall commented 5 years ago

你好,你这个问题我这几天压测dubbo的接口,应该刚好遇到,这里总结一下,也回复给你。 我遇到的需求是:压测dubbo接口,我需要做的是:

  1. 写好dubbo的客户端,需要在pom文件中引用dubbo的依赖,zookeeper的依赖,Jmeter-java的依赖(已经包含core的依赖,不需要再次依赖Jmeter-core)。
  2. 写访问dubbo的代码,需要继承 AbstractJavaSamplerClient 类,或者 实现JavaSamplerClient 接口。细节是在setupTest中写dubbo的配置初始化,runTest 中写实际的dubbo服务请求。
  3. 将这个代码打包成jar包,推荐jar包仅仅打包代码本身,而不要全量的lib(默认的打包全量的,可能会遇到jar包中代码结构不对,classNotFoundException 的错误)。
  4. 再打一个全量的jar包,解压后看其中的lib,和Jmeter自己的lib其中的jar包做对比,把名字不同的,都放进去,以免确实,造成class找不到错误。
  5. 把自己写的dubbo 客户端的jar包(仅包含测试代码的),放到Jmeter的lib/ext 下,其实直接放到lib 下也可以,但是放到ext下就是更清晰一点儿。
  6. 直接启动Jmeter(因为我们是对比添加的jar包,所以slf4j 冲突会遇不到),如果遇到其他引用冲突,直接删除(我没有遇到)。
  7. 启动Jmeter后,直接创建一个javaRequest 的Sampler,自动就会在下拉框中找到新建的测试dubbo的类(是因为继承了 AbstractJavaSamplerClient),配置好压力后,直接压测即可。

以上是Jmeter自己压测,自己创建java请求,压测dubbo的大致步骤。 那么到平台上,要怎么做呢?重复的就不说了,说下不同的:

  1. 平台的pom文件中,引用dubbo相关的:dubbo的starter 和 zookeeper 的。
  2. 在tomcat的webapps 中, stressTestPlatform war包解压出来的文件夹下,找到lib目录,将自己生成的jar包放到这里,启动平台。 遇到的小问题:
  3. 如果将测试平台设置成为根目录启动,则war包因为tomcat的配置,应该不会自动解压,那么需要手工解压war包,将自己的jar放到lib下。
  4. 如果jar包换了之类的,需要重启平台代码,以重新加载自己的jar。
  5. 放到平台引用的Jmeter 目录下,并不好用,因为仅仅是加载了classpath,没有真正的加载其中的jar包(因为平台引用了Jmeter 的jar,不能重复加载)。

那么回到你的问题,猜测:

  1. 你自己封装的jar 包,目录结构不对, 参考 https://www.jianshu.com/p/080d6a920e10
  2. 你是放到平台引用的Jmeter目录下了,没放到平台的自己的lib中。

建议:

  1. 先使用Jmeter 自己启动一下看看,排除猜测1.
  2. 看着点启动的日志,里面会有详细的异常。

思考:

  1. 能不能有一个管理jar包界面,上传自己的jar包,然后不用频繁重启平台,请求的时候才加载这些jar包,让jar包实时生效的。
    这是可以做的,但是比如上面的例子,虽然自己的jar包可以这么干,但是dubbo 的还是需要写到pom文件中的,但是也比较省事了。
  2. 啥时候做? 要看是否频繁遇到这种。目前平台还有一些小功能要微调,这个大功能稍微后排。

最后,感谢你的issue。

huzhiwei99bill commented 5 years ago

hi,这几天都在看你写的平台代码, 写的很棒啊,非常感谢您,让我学到了很多东西

另外针对 您回答的dubbo这块压测,有开源的dubbo插件 这样大家测试dubbo接口的话 就不用写代码了,自然jar包冲突等问题也自然规避了;需要把dubbo及依赖的jar丢到jmeter jar包路径下 这个都是开源版本 不多聊哈

我们 再回到主要问题哈

针对非http协议的性能需求 性能脚本 1、比如dubbo的接口 我们有dubbo插件 引用dubbo插件包及其依赖包 丢到平台上 但是我们测试需求多变,比如我要测rocketmq *mq rpc等等 很多,所以实现AbstractJavaSamplerClient 类方式写脚本会成为一种常态 这种诉求很高很高

所以平台要设计支持这块,目前我看平台代码里 更多是处理非jar包方式的; 我这边考虑设计如果平台支持的话可能有2种方式解决jar包冲突方式,类隔离方案 1、简单粗暴的方式,jvm进程隔离 每个用户使用平台进行压测任务 1个jmeter controller(1台机器可以起多个controller) N个jmeter slave节点(每个slave 一台机器) 这样在每个集群节点上都放置脚本及依赖jar 单独解决这个脚本对应的jar 跟jmeter之间的冲突

2、多用户脚本 1个controller多agent方式 这种方式我还不能肯定,哈哈 期待与您沟通,加速平台支持非http协议 我的qq 805002329

zyanycall commented 5 years ago

hi,这几天都在看你写的平台代码, 写的很棒啊,非常感谢您,让我学到了很多东西

另外针对 您回答的dubbo这块压测,有开源的dubbo插件 这样大家测试dubbo接口的话 就不用写代码了,自然jar包冲突等问题也自然规避了;需要把dubbo及依赖的jar丢到jmeter jar包路径下 这个都是开源版本 不多聊哈

我们 再回到主要问题哈

针对非http协议的性能需求 性能脚本 1、比如dubbo的接口 我们有dubbo插件 引用dubbo插件包及其依赖包 丢到平台上 但是我们测试需求多变,比如我要测rocketmq *mq rpc等等 很多,所以实现AbstractJavaSamplerClient 类方式写脚本会成为一种常态 这种诉求很高很高

所以平台要设计支持这块,目前我看平台代码里 更多是处理非jar包方式的; 我这边考虑设计如果平台支持的话可能有2种方式解决jar包冲突方式,类隔离方案 1、简单粗暴的方式,jvm进程隔离 每个用户使用平台进行压测任务 1个jmeter controller(1台机器可以起多个controller) N个jmeter slave节点(每个slave 一台机器) 这样在每个集群节点上都放置脚本及依赖jar 单独解决这个脚本对应的jar 跟jmeter之间的冲突

2、多用户脚本 1个controller多agent方式 这种方式我还不能肯定,哈哈 期待与您沟通,加速平台支持非http协议 我的qq 805002329

感谢对平台的代码的肯定。 jar包冲突,类冲突确实会比较麻烦,这个还需要多考虑考虑。 尤其slave端,对它的控制太少了。 其实脚本对应的jar包可以和参数化文件一样上传,然后脚本中配置jar包的地址在脚本的同级目录下。但是这样也仍然会有slave端的class冲突问题(未来会想slave的日志监控,这样会直观看到为什么错误)。 其实这些都是Jmeter平台自身存在的问题,我们都是在尝试优化。 再次感谢。