此Spring Cloud 项目采用的技术栈为
- 注册中心 Spring Cloud Eureka
- 配置中心 Spring Cloud Config
- 链路追踪 Zipkin
- 分布式事务TxLcn
- 一些其他组件
硬件条件
- CPU AMD Ryzen 7 2700 3.20GHz
- 内存16GB
在实际中测试登录接口,并发量为250TPS左右(每秒处理250个请求)
同样一台电脑Redis的吞吐量为7W左右,差距太大,接下来分析问题产生的原因
发现问题
编写一个无业务逻辑接口,排除数据库的影响,直接返回请求成功的结果,代码如下
@RestController
public class TestController implements BaseRestController {
@RequestMapping("/test")
public RestResponse<TestSpeedResult> test(){
TestSpeedResult result = new TestSpeedResult();
return this.createReponse(result);
}
}
对此接口进行Jmeter压力测试,线程数为500,无限制循环调用,产生的结果如下图
发现两个问题
- 吞吐量为375左右,非常慢,要知道,这个接口无任何处理请求。
- 最大处理时间达到的惊人的31秒(测试进行了32秒),说明有请求一直处于阻塞状态。
问题分析
从这种情况可以看出,问题和数据库无关,纯返回数据的接口的速度都非常慢
拿出我的绝手好活 VisualVm,Java自带的强大神器,拥有监控内存,监控CPU的性能,追踪等各种插件。
使用CPU抽样,查看是哪些方法花费太多时间
可以看到,有个名为
findFirstNonLoopbackAddress的函数居然占据了CPU百分之97.7的时间
我们以debug模式启动应用,在函数头下断点,开启Jmeter,函数成功断下来,我们看下调用栈
从第二条数据可以看出,该方法是由zipkin调用,大概查看了下源码,是用来上报Trace信息所调用的。上报追踪信息是影响性能的主要因素。
解决及验证
修改配置文件,关闭链路追踪
设置spring.zipkin.enabled 为false。
重新使用Jmeter进行吞吐量测试
可以看到吞吐量已经道道11660左右。
吞吐量提高了31倍,恢复了正常水准。
总结
Zipkin会拖慢系统速度,建议在生产环境关闭,在开发环境开启。避免影响整个系统性能。
另外, 通过Zipkin配置调整优化应该也能解决这个问题,这个就需要小伙伴们自己去探索了~