现象
接口TPS在160左右无法上升
排查
9-27排查
让测试重新压测。
通过线程繁忙查询,基本为如下
可以看到大多数线程为Druid连接池进入等待取连接状态。
Druid线程池问题
根据源码查看,定位到此方法主要根据maxWait的值来设置等待时间。
下面进行arthas链路追踪
可以看出,maxWaitMills使用了默认值 -1 (即:maxWait的默认值,即如果连接池没有空闲连接,获取连接的线程则会一直等待下去。)
后续就是漫长的配置查询之路
项目是通过spring.datasource.type=com.alibaba.druid.pool.DruidDataSource引入druid连接池,通过这种方式引入配置文件中的其他属性是无法自动注入。要使该配置生效,需要使用javaBean的方式配置。
@Configurationpublic class DruidConfig { @Bean // 将所有前缀为spring.datasource下的配置项都加载DataSource中 @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource() {
return new DruidDataSource(); }
}
重新压测
修改代码后进行重新压测。
可以看到性能提高了10倍。
但是目前仍然存在问题,性能存在不稳定性
9-28排查
让测试重新压测。
使用arthas profile导出cpu的火焰图。
分别是4种数据库查询的场景。
火焰图显示主此方法中主要占用cpu的为这4个sql查询(其他都是正常的链路)。
排查数据库
通过了解得知,此服务是通过连接mycat代理mysql。
让测试直接压测mycat(其地址和现在排查服务地址一致)。
发现性能真好
排除mycat/mysql的问题
接口详细分析
通过对其中一个查询进行tt分析。
- tt -t class名字 -n 次数
- tt -i 详细的值
可以看出在某个时间下,他会出现耗时由几毫秒变成几百毫秒的场景。
得出结论:数据库查询不稳定,需要认真定位
通过arthas trace查询超过100ms的请求
trace 包名 方法名 -n 10 ‘#cost > 100’
通过其代码排查,此业务(插入日志)耗时过多,目前将其改成异步,使用@Async注解