You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat停止时出现pool-(x)-thread-(y)阻塞线程导致关闭耗时久如何解决

根因定位

你遇到的是mariadb-java-client 2.3.x版本的已知Bug:该版本驱动内部会默认创建一个无显式销毁逻辑的异步线程池,用于处理连接超时检测、异步批量查询等逻辑,线程命名就是默认的pool-(x)-thread-(y)格式,应用停止时驱动不会主动关闭该线程池,进而导致Tomcat容器回收web应用资源时阻塞,触发内存泄漏告警。

验证方法

在应用启动参数中添加如下配置,禁用驱动内部的异步超时线程池:

-Dmariadb.enableAsyncTimeouts=false

重启应用后再执行停止操作,如果阻塞线程消失即可确认是该驱动问题导致。

解决方案

  1. 最优方案:升级驱动版本
    直接升级mariadb-java-client到2.7.10+或者3.0.3+版本,上述版本已经修复了线程池未主动关闭的问题,和Spring 4.x/5.x版本兼容性良好,无需修改业务代码。
  2. 临时兼容方案(无法升级版本时使用)
    在Spring Bean的销毁逻辑中主动关闭数据库连接池,示例代码如下:
@PreDestroy
public void closeDataSource() throws SQLException {
    if (dataSource != null) {
        dataSource.close();
    }
}

也可以直接在数据库连接配置中添加禁用异步超时的参数,避免内部线程池创建:

spring.datasource.url=jdbc:mariadb://xxx:3306/xxx?enableAsyncTimeouts=false
  1. 长期排查优化
    后续所有自定义线程池、第三方依赖的线程池都尽量配置自定义线程工厂,给线程加上业务标识前缀,避免默认命名导致的问题排查困难。

额外排查方向

如果处理完驱动问题后仍存在同格式阻塞线程,可以排查其他未配置销毁逻辑的中间件客户端(Redis、MQ客户端等),这类组件如果使用默认线程池配置,也会生成pool-(x)-thread-(y)格式的线程,可通过Arthas的thread命令过滤对应线程,查看其上下文类加载器关联的依赖,快速定位来源。


内容的提问来源于stack exchange,提问作者Tobia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:54:03