现象:
测试对平台接口进行压测,平均每个接口TPS为700多,无法继续压上去。
压测结果
排查:
1.服务争抢资源
227启着十几个java进程,还有中间件,mysql,python。如果把这些服务都关掉的话,上1000肯定是没有问题的。
通过查看:每秒上下文切换次数 四万多
2.查看项目线程状态
让测试重新开始压测,通过arthas命令查看当前项目占用线程状态(thread)
可以看到大部分进程进入BLOCKED状态,进入tomcat线程查看堆栈信息。
可以看出具体阻塞的原因是tomcatEmbeddedClassLoader
3.查看出现锁的具体源码
投机取巧,先对loadClass进行watch操作,查看详细的出入参数
可以看出参数为org.springframework.cloud.context.environment.EnvironmentChangeEvent。
并且抛出的异常为找不到org.springframework.cloud.context.environment.EnvironmentChangeEvent此类。
回归死锁堆栈信息
回顾tomcat实现的原理
tomcat对请求到的请求会进行封装
doPost->封装成event->由指定event监听进行处理此请求。
在详细的信息中可以看到ApplicationListener由RefreshScopeRefreshedEventListener实现,并且其中isAssignable出现了死锁。
其中的className为org.springframework.cloud.context.environment.EnvironmentChangeEvent。
也就是watch报错的参数。
并且可以看到这个包并非tomcat自己实现的包,而是第三方包com.ulisesbocchio.jasyptspringboot.caching
4.排查出错的包
查看包的详细
通过pom寻找,查到我们导入了他的依赖
并且进行了stater注入
解决
问题一:org.springframework.cloud.context.environment.EnvironmentChangeEvent 类
BAS平台项目不是分布式服务,没有此类,所以这就是导致死锁报错的原因。
是否需要引入cloud组件来解决此问题
问题二:是否可以修改此依赖来解决
当前版本为3.0.3
com.github.ulisesbocchio
jasypt-spring-boot
${jasypt.version}
目前去除了stater版本,改为此依赖。
打包部署后,测试重新压测。TPS达到了8K多。
但是修改此依赖导致其他配置要修改(如密码明文配置等)还需要重新适配
问题三:是否已经出现版本适配此bug
通过查询
官方已经发现此问题,升级到3.0.4即可