生产tomcat线程阻塞问题分析
大约 1 分钟
生产tomcat线程阻塞问题分析
现象
当大量的请求到服务,过一会,服务无法响应请求,k8s配置了健康检查,服务被k8s重启
分析
让运维的同学把thread和heap dump了下来,打开一看,全部tomcat的线程阻塞在Druid连接池上
线程情况
所有的tomcat线程堵塞在com.alibaba.druid.pool.DruidDataSource.takeLast
,该方法是从Druid的连接池取出连接,当线程池没有空闲的时候,一直阻塞等待。
堆文件分析
- notEmptyWaitThreadPeak:当前等待连接池的线程数
- poolingCount:连接池中的连接数
- maxActive:连接池的最大容量
- activeCount:当前活跃(在执行sql的连接)数
通过上图知道在一个容量为8的连接池中,有200个线程在等待一个poolingCount为0的连接池,刚好对应上tomcat的连接数
解决
项目使用了ShardingSphere做分表分库,在配置ShardingSphere时,没有对每个数据库配置连接池大小,使用了默认配置,默认maxActive最大为8,当有慢sql阻塞的时候,很容易就出现整个服务阻塞,应当增大连接池的大小
项目中配置了spring.datasource.druid.max-active
大小,但是shardingsphere不兼容该配置,需要像一下方式配置
spring.shardingsphere.datasource.<datasource-name>.max-active = xxx