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

为何Hikari连接池存在大量等待连接?如何排查定位?

排查Hikari连接池耗尽问题的实用方法

从你提供的日志来看,HikariPool-1的所有10个连接都处于活跃状态,没有空闲连接,还有大量请求在等待获取连接——这典型是连接泄漏或者连接被长时间占用导致的。结合你的技术栈(Hibernate、MS SQL、Azure K8s),我整理了以下排查步骤:

1. 启用Hikari的连接泄漏检测

这是最快定位泄漏点的方法,Hikari自带了连接泄漏检测机制。你只需要在配置中添加:

spring.datasource.hikari.leak-detection-threshold=2000

(单位是毫秒,这里设置为2秒,你可以根据业务场景调整阈值)

当连接被获取后超过设定时间没有归还,Hikari会在日志中打印这个连接的调用堆栈,直接告诉你是哪段代码获取了连接但没释放。日志里会出现类似Connection leak detection triggered的标记,跟着的堆栈就是问题代码的具体位置。

2. 排查Hibernate的Session与连接管理

连接通常和Hibernate Session绑定,所以重点检查:

  • 是不是手动调用了session.openSession()但没在finally块中关闭?推荐优先使用sessionFactory.getCurrentSession()(由Spring或容器自动管理Session生命周期),避免手动管理的疏漏。
  • 有没有慢查询占用连接?开启Hibernate的SQL日志,直观查看哪些SQL执行时间过长:
    logging.level.org.hibernate.SQL=DEBUG
    logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
    
    这样能看到完整的SQL语句和参数,快速定位没有索引的大表查询、复杂关联查询这类耗时操作——它们会让连接长时间被占用,导致池子里的连接被耗尽。

3. 检查K8s部署与连接池配置合理性

  • 单Pod连接池大小与总连接数:如果你的应用在K8s中部署了多个Pod,每个Pod的Hikari池大小是10,那么总连接数是Pod数量 × 10,要确保这个总数不超过MS SQL Server的最大连接数(默认是1000,可执行SELECT @@MAX_CONNECTIONS查看),同时要扣除其他应用的连接占用。
  • Pod重启后的僵尸连接:K8s重启Pod时,如果应用没有优雅关闭,可能会导致MS SQL中残留未释放的僵尸连接,占用数据库资源。可以执行以下SQL清理闲置过久的连接:
    SELECT * FROM sys.dm_exec_sessions WHERE status = 'sleeping' AND last_request_end_time < DATEADD(minute, -5, GETDATE())
    

4. 导出线程栈分析连接占用情况

在K8s的Pod中,先找到应用的Java进程ID(用ps aux | grep java),然后导出线程栈:

jstack <pid> > thread-dump.txt

打开线程栈文件,搜索HikariPool或者Connection相关的线程,查看这些线程的调用栈,找到正在占用连接的代码逻辑。比如你会看到线程卡在Hibernate的查询方法、事务提交方法,或者外部API调用上(如果事务错误地包裹了非DB操作)。

5. 从MS SQL Server端监控连接状态

直接在数据库端查看连接的详细情况,能帮你定位到具体的问题SQL:

  • 查看所有Hikari相关的会话:
    SELECT session_id, program_name, login_time, last_request_start_time, status
    FROM sys.dm_exec_sessions 
    WHERE program_name LIKE '%Hikari%'
    
  • 查看正在执行的请求,排查阻塞或长时间运行的SQL:
    SELECT r.session_id, s.program_name, r.status, r.command, t.text
    FROM sys.dm_exec_requests r
    JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
    CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
    WHERE s.program_name LIKE '%Hikari%'
    
    这里的t.text就是正在执行的SQL,找到运行时间长的语句后,回到应用代码中针对性优化。

6. 检查事务边界是否合理

长事务是连接被长时间占用的常见原因:

  • 检查@Transactional注解是否被误用,比如把它加在了包含外部API调用、文件IO等耗时操作的方法上——事务会持有连接直到方法结束,非DB操作会让连接被白白占用。
  • 确保所有事务都能及时提交或回滚,避免因为异常导致事务未关闭(比如try块中开启事务,finally块中没有确保提交/回滚的逻辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:53:17