高并发下JDBC连接池耗尽需从选型、配置、代码、监控四层协同解决:首选HikariCP,合理调优maximumPoolSize等参数,严格用try-with-resources防泄露,并通过JMX和APM实时监控。

高并发下 JDBC 连接池耗尽,本质是连接申请远超池子供给能力,或连接未及时归还。解决不是靠堆参数,而是从选型、配置、代码、监控四层协同入手。
选对连接池:HikariCP 是当前最优解
HikariCP 采用无锁设计(ConcurrentBag),在千级线程争抢连接时延迟极低,启动快、依赖少、出问题易定位。相比 DBCP2 或 C3P0,它默认配置更合理,性能更高,且社区维护活跃。
- Maven 引入稳定版(如 5.0.1):
<groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> - 避免混用多个池实现,尤其不要在 Spring Boot 中同时引入 HikariCP 和 DBCP2 依赖,以防自动配置冲突
关键参数必须按场景调优
默认值只适合开发环境。生产中需结合数据库最大连接数(如 MySQL 的 max_connections=200)、应用线程模型和压测结果来设。
- maximumPoolSize:设为 DB 最大连接数的 70%~80%,例如 200 → 建议 140~160
-
minimumIdle:保持常驻空闲连接,建议设为
maximumPoolSize的 1/3~1/2,缓解突发流量 - connectionTimeout:获取连接最长等待时间,推荐 30000ms(30秒),太短易抛异常,太长阻塞线程
-
maxLifetime:连接最大存活时间(如 1800000ms = 30分钟),强制刷新老化连接,防止 MySQL 的
wait_timeout导致通信失败 - leakDetectionThreshold:设为 60000ms(60秒),自动标记未归还连接,快速定位泄露点
代码层面严防连接泄露
池子再大,用完不还也会撑爆。泄露一个连接,就少一个可用连接;累积数小时,服务可能整体卡死。
立即学习“Java免费学习笔记(深入)”;
- 所有数据库操作必须用 try-with-resources,自动关闭
Connection、Statement、ResultSet - 事务边界要显式控制:开启后必须
commit()或rollback(),否则连接长期绑定在线程上 - 禁止在定时任务、异步线程或 long-running 循环里持有 Connection 不释放
- Spring 环境下优先用
@Transactional,但需确认传播行为(避免REQUIRES_NEW频繁开新事务)
监控连接池真实状态,别等报错才响应
连接池不是配完就一劳永逸。要主动看它“喘不喘气”。
- 启用 JMX 监控:通过
HikariPoolMXBean实时查活跃数、空闲数、等待线程数 - 加日志观察:在
logback-spring.xml中开启org.springframework.jdbc和连接池类 DEBUG 日志 - 重点关注指标:threadsAwaitingConnection > 0 表示已开始排队;activeConnections 接近 totalConnections 是预警信号
- 配合 APM 工具(如 SkyWalking、Prometheus + Grafana)做趋势分析,提前扩容或优化慢 SQL


















