电脑工场
白蓝主题五 · 清爽阅读
首页  > 网络基础

连接池怎么调才不拖慢服务?几个实战中踩过的坑

公司后台接口突然变慢,监控显示数据库响应时间飙升,但查 SQL 执行计划又没问题。最后发现是连接配置太保守:最大连接数设成 10,高峰期排队等连接的线程堆了上百个——这不是数据库慢,是连都连不上。

别把连接池当“开关”,它是个水龙头

很多人以为开个连接池就万事大吉,其实它更像厨房水龙头:开太小,接杯水要等半天;开太大,水管爆了(数据库扛不住)。关键不是“开了没”,而是“开多大、怎么流、堵了怎么办”。

四个最常被忽略的优化点

1. 初始连接数别设为 0
冷启动时第一个请求要等连接建立,耗时可能飙到几百毫秒。哪怕只是 2~3 个预热连接,也能抹平首屏卡顿。Spring Boot 默认 initialSize=0,上线前记得改:

spring.datasource.hikari.initialization-fail-timeout=0
spring.datasource.hikari.connection-init-sql=SELECT 1
spring.datasource.hikari.minimum-idle=3

2. 最大连接数 ≠ 数据库最大并发数
MySQL 默认 max_connections=151,但你的应用有 5 台机器,每台配 50 个最大连接,实际打过去就是 250 个连接——早超了。建议单机最大连接数控制在数据库总连接数的 1/3 以内,并留出 DBA 维护通道。

3. 空闲连接别“赖着不走”
设置 idle-timeout(比如 10 分钟),避免大量空闲连接占着坑不干活。HikariCP 默认是 10 分钟,但有些老项目用的是 DBCP,idleTimeout 配置项名都不一样,得翻源码确认。

4. 连接泄漏比慢查询更可怕
一次忘记 close(),连接就挂在池子里不动了。HikariCP 开启 leak-detection-threshold=60000(单位毫秒),超 60 秒没归还就打告警日志。线上真见过一个定时任务漏关 ResultSet,两天吃掉全部连接,整个服务假死。

看一眼你的真实使用率

别光看配置文件。加个 Prometheus + Grafana,监控这几个指标:

  • hikaricp_connections_active(当前活跃连接数)
  • hikaricp_connections_idle(空闲连接数)
  • hikaricp_connections_pending(排队等待连接的线程数)

如果 pending 长期大于 0,说明池子小了;如果 active 峰值只到 max 的 30%,那 max 就是拍脑袋定的,该砍。

某电商大促前压测,发现连接池平均利用率不到 40%,果断把每台机器的 maxActive 从 80 降到 45,省下 20% 内存,且响应时间更稳——连接不是越多越好,够用、可控、能回收,才是健康。