连接池耗尽服务全挂,排查3天才发现HikariCP默认值全是坑

简介: 本文记录一次线上服务雪崩事故的3天排查过程:核心服务RT从80ms飙升至30秒,根源竟是HikariCP三个开发默认值——maximum-pool-size=10、connection-timeout=30s、idle-timeout=10分钟——在高并发下形成乘法级灾难。文章详解问题原理,并给出生产级配置方案。

那天凌晨3点,告警短信把整组人炸醒了。

监控大屏上,一个核心服务的RT从平时的80ms飙到了30秒,所有接口全部超时。看Tomcat线程池——200个线程全部在跑,没有一个空闲。再看数据库——MySQL连接数只有12个,远没到上限151。数据库不慢,服务却崩了。

运维第一反应是重启。重启后好了10分钟,又崩。再重启,又是10分钟。

接下来3天的排查,最后锁定的问题只有一行配置。

排查第一天:看起来只是"慢"

从日志入手,错误信息很明确:

java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, 
request timed out after 30000ms.
    at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:734)

翻译成人话:获取数据库连接等了30秒还没拿到,直接抛异常

这是 HikariCP 连接池的典型报错——连接池里的连接不够用了,新的请求排队等了 connection-timeout 的时长(默认30秒),还是没等到,报错退出。

第一天的排查方向:是不是有慢SQL把连接占住了?查了MySQL慢查询日志,确实有一条统计SQL跑了3秒——原因是某个表昨天新加了200万行数据,负责统计的索引没建。

加了索引后,SQL从3秒降到50ms。重启服务,以为解决了。

凌晨4点,又崩了。一模一样的报错。

排查第二天:200多个线程全卡在一个地方

第二天做了线程dump。不看不知道,一看吓一跳:

"http-nio-8080-exec-187" #187 daemon prio=5 os_prio=0 tid=... waiting on condition
   java.lang.Thread.State: TIMED_WAITING
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:358)
        - waiting on <0x00000006c0d4e8f0>
"http-nio-8080-exec-188" #188 daemon prio=5 os_prio=0 tid=... waiting on condition
   java.lang.Thread.State: TIMED_WAITING
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:358)
        - waiting on <0x00000006c0d4e8f0>

从 #187 到 #200+,所有线程都在 HikariPool.getConnection() 上排队。Tomcat的200个线程池全部被这些等待连接的线程占满了,新来的请求根本没线程处理,直接被拒绝

问题变成了:为什么连接池里的连接不够用?

看了一下配置——问题初步浮出水面:

# 当前配置(就是Spring Boot的默认值,一直没改过)
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.connection-timeout=30000

10个连接。这个服务的正常QPS是100,每个数据库查询平均50ms,理论上 10 / 0.05 = 200 QPS 上限,100 QPS 应该够用。

但问题在于:当出现一个3秒的慢查询时,整个池瞬间就崩了

第三天:终于找到了根因——不是1个参数的锅,是3个默认值联手搞的事

算一笔账,你就能明白为什么"10个连接+30秒超时"是生产环境的定时炸弹:

灾难推演:假设QPS=100,10个连接。当1条SQL从50ms突变为3秒(缺索引/数据量暴涨/锁等待),有效吞吐量从 10/0.05=200 QPS 骤降到 10/3=3.3 QPS。每秒钟有 97 个请求在排队等连接。每个请求最多等 connection-timeout=30秒才报错。30秒 × 97个/秒 = 2910个请求在Tomcat线程池里排队。而Tomcat默认只有200个线程——线程池先于连接池被击穿,整个服务假死。

重新审视 HikariCP 的默认值,有3个参数是专门为开发机设计的,不是为生产环境设计的

参数

默认值

开发机的逻辑

生产环境的现实

maximum-pool-size

10

本地就一个用户,10个连接绰绰有余

生产QPS 100+,一条慢SQL就让10个连接全部占满

connection-timeout

30000(30秒)

本地请求少,等久一点无所谓

30秒超时意味着线程池被排队线程占满,其他正常请求全被拒绝

idle-timeout

600000(10分钟)

连接池小,回收快慢无所谓

空闲连接10分钟才回收,连接长时间不用可能已被数据库端断开,下次使用直接报错

单个看,每个默认值都有它的道理。但三个组合在一起,高并发场景下的效果是乘法级的灾难

  • maximum-pool-size=10 → 吞吐天花板极低
  • connection-timeout=30000 → 出问题时线程堵30秒才退出,堵住的线程又占着Tomcat线程池
  • idle-timeout=600000 → MySQL端 wait_timeout 如果设了较短值(比如某些云数据库默认60秒),连接在池里闲置10分钟早就被数据库关了,取出来用就报 CommunicationsException

三个参数的Production-Ready配置

1. maximum-pool-size:不是越大越好,但要算清楚

先看数据库能承受多少连接:

-- 查数据库最大连接数
SHOW VARIABLES LIKE 'max_connections';
-- 查当前已用连接数
SHOW STATUS LIKE 'Threads_connected';

假设MySQL最大连接数151,系统账号和监控占20个,剩下131个给业务。如果线上有4个应用实例,每个实例的连接池大小上限 = 131 / 4 ≈ 32。

然后再用业务公式验证:

# 公式:连接池大小 = 峰值QPS × 平均数据库查询RT(s) × 1.5
# 示例:峰值QPS=200,平均SQL RT=50ms=0.05s
# → 200 × 0.05 × 1.5 = 15 个连接
# 但必须保留慢查询buffer:再预留30%
# → 15 × 1.3 ≈ 20 个连接
spring.datasource.hikari.maximum-pool-size=20

一个经验值:单实例一般配 20~50,不要超过数据库最大连接数 ÷ 实例数的 80%。10 是绝对不够的。

2. connection-timeout:30秒太长了,3秒就够了

你在生产环境等过一个30秒的请求吗?用户早就关页面了。

connection-timeout 的逻辑是"等多久还没拿到连接就抛异常"。30秒意味着:

  • 用户等了30秒才看到报错(他10秒前就已经关了页面)
  • 这30秒里Tomcat线程一直被占用,堵着后面的正常请求
  • 如果30秒内有3000个请求进来,3000个线程全堵着——Tomcat线程池瞬间爆炸
# 设置3秒超时——如果3秒拿不到连接,说明连接池大概率已经崩了
# 快速失败比长时间等待要好得多
spring.datasource.hikari.connection-timeout=3000

快速失败原则:3秒拿不到连接就报错,用熔断/降级兜底,而不是让所有请求堵30秒然后把整个服务拖死

3. idle-timeout 和 max-lifetime:别让你的连接被数据库偷偷关了

最后一个坑:HikariCP里的连接闲置太久,数据库那边早就断开了,拿出来用就报错。

# MySQL默认 wait_timeout = 28800(8小时),一般不改
# 但很多云数据库RDS的默认值不同,有些只有60秒
# HikariCP 的 max-lifetime 必须比数据库的 wait_timeout 短
# 一般设 30分钟(1800000ms)
spring.datasource.hikari.max-lifetime=1800000  # 30分钟,默认值OK
# idle-timeout 要小于 max-lifetime
# 设置5分钟——连接5分钟没用就回收,不让数据库端先断开
spring.datasource.hikari.idle-timeout=300000    # 5分钟
# 额外加 keepalive ——定期ping保持连接活跃(HikariCP 4.0+ 支持,最低间隔30秒)
spring.datasource.hikari.keepalive-time=60000   # 每60秒ping一次

一张表记住所有配置

参数

默认值(坑)

生产建议值

为什么

maximum-pool-size

10

20~50

按 QPS×RT×1.5 计算

connection-timeout

30000

3000

快速失败,堵30秒会拖死线程池

idle-timeout

600000

300000

5分钟回收,防止数据库端先断

max-lifetime

1800000

1800000

默认OK,但必须小于MySQL wait_timeout

keepalive-time

0(关闭)

60000

每60秒ping保活

写在最后

HikariCP 本身是一个非常好的连接池——启动快、开销低、性能顶级。问题不在于它,在于默认值是为"本地开发"这个场景设置的。Spring Boot 把它作为默认连接池时,并没有把默认值改成生产级别的。

这件事的教训不只是"记得改配置"——上线前检查清单里,连接池配置必须是必查项。10个连接在本地跑得飞起,到了生产就是一颗不知道什么时候爆炸的定时炸弹。

你的项目里 HikariCP 的这几个参数改过了吗?还在用默认值的话,下次高并发可能就不是排查3天的问题了。

相关文章
|
29天前
|
人工智能 JSON 算法
API选品 vs 人工选品:效率与精准度的终极对决
本文剖析电商等领域“选品之争”:API自动化选品以高效、可扩展见长,擅处理海量数据;人工选品则胜在文化洞察、战略判断与伦理把关。二者非替代而是互补——API广筛初排,人工精筛校准,闭环反馈持续优化。未来属于“AI增强型专家”。
|
29天前
|
Web App开发 人工智能 jenkins
还在手写测试报告?推荐一款 AI 测试Skill:只需一句指令,自动生成专业定制化测试报告!
`api-report-generator`是一款AI驱动的接口测试报告生成工具,一句指令即可将执行数据自动转化为含11大专业分区、风险分级、优化建议及Allure联动的决策型HTML报告,告别“数字堆砌”,让报告真正有人看、能决策。
159 0
还在手写测试报告?推荐一款 AI 测试Skill:只需一句指令,自动生成专业定制化测试报告!
|
29天前
|
存储 移动开发 小程序
圈子论坛软件系统商业版开发搭建全攻略:社交圈子系统多端适配与行业场景落地指南
本圈子系统采用UniApp+ThinkPHP6技术栈,一套代码覆盖微信小程序/H5/APP多端;支持付费入圈、会员体系、实时聊天与内容风控,集成支付、地图、云存储及AI安全审核,兼顾高效开发与商业合规。
148 0
圈子论坛软件系统商业版开发搭建全攻略:社交圈子系统多端适配与行业场景落地指南
|
29天前
|
人工智能 自然语言处理 搜索推荐
AI Shopping,开始进入信任时代
Phia事件引发对AI购物时代的深层反思:当购物助手从“帮人找商品”转向“代人做决策”,联盟佣金、Cookie Stuffing与数据隐私暴露出核心矛盾——消费者是否愿将决策权(Decision Authority)托付给AI?信任,而非算力,正成为AI商业化的真正瓶颈。(239字)
112 0
|
2月前
|
Linux API 开发者
MarkText:一款被低估的开源 Markdown 编辑器
MarkText 是一款 **被严重低估** 的编辑器。它没有 Obsidian 的插件生态,也没有 Notion 的协作能力,但它做到了很多编辑器没做好的事:**把写 Markdown 这件事本身做到极致**。 干净的界面、流畅的实时预览、体贴的三种编辑模式、完整的规范支持,再加上 MIT 开源免费——如果你是一个纯粹的写作者,MarkText 就是你需要的那个工具。
1012 3
|
5月前
|
人工智能 安全 Java
先收藏|OWASP Top10 第二坑:Java开发踩过的配置漏洞
OWASP 2025榜单显示,“安全配置错误”高居第二,100%被测Java应用中招,漏洞超71.9万次!本文揭露6大典型配置风险:默认账户未改、Swagger未禁用、报错信息裸奔、云服务权限失控、安全头缺失、密钥硬编码,并附真实案例与修复指南。(239字)
|
29天前
|
人工智能 监控 测试技术
银行业AI架构:从裸调API到六层技能体系
# 银行AI智能体架构实战:从单体到Skill协同的技术演进 ## 痛点:银行IT架构的三重困境 走在任何一家银行的科技部走廊里,你都能听到同样的叹息:系统又慢了、需求又排不上、监管又来查了。这不是某一家银行的困境,而是整个银行业IT架构的共性问题。我们把它拆解为三重困境。 **困境一:单体系
|
2月前
|
人工智能 架构师 Java
告别AI工具选择困难症!2026 Java开发者效率清单
2026年,Java开发者面临“工具多、协同弱”的困局。本文提出“三层过滤”选型法:Ollama/Copilot作轻量辅助;飞算JavaAI为智能核心——内置10个专家Agent,支持可干预架构设计、上下文感知对话与规范代码生成;Spring AI+LangFuse补全可观测性。告别堆砌,拥抱懂工程的“AI大脑”。
|
4月前
|
SQL 人工智能 安全
Cursor月活破500万、Claude Code SWE-bench登顶80%,2026 AI编程工具横评最缺的其实是“稳”
2026年AI编程工具横评聚焦“快准强”,却忽视关键——“稳”。Cursor月活破500万、Claude Code SWE-bench登顶80%,但开发者真正焦虑的是交付质量与可维护性。飞算JavaAI以“工程治理”破局:自动适配规范、修复安全漏洞、保障全链路可追溯,让AI代码真正可靠、合规、可审。
|
5月前
|
SQL 人工智能 安全
别人都在“养龙虾”,我靠这个AI工具箱3小时搞定“祖传代码”
2026年,“OpenClaw龙虾”AI智能体席卷中国,但代码质量成最大瓶颈。飞算JavaAI工具箱应运而生:10秒重构面条代码、一键修复依赖冲突、自动堵住SQL注入漏洞、生成3万字文档、秒建高覆盖单元测试——专为祖传Java系统“拆弹”,让AI真正敢用、能用、好用。(239字)