连接从哪里来:连接池原理
每次访问数据库都新建连接,握手、鉴权、建立会话的开销不小,高并发下连接一多数据库就被拖垮。连接池的思路是预先建好一批连接放在池里,应用借了用完再还,连接复用省掉反复建连。HikariCP 是 Java 生态最常用的连接池,靠极小的开销做到了高性能。
- 池化连接复用,减少建连开销。
- 参数核心数、最大数与获取超时。
- 泄漏借了不还导致池被耗尽。
- 监控通过指标观察池的健康度。
池的参数:核心数、最大数与队列
连接池三个关键参数:最小空闲连接数、最大连接数、获取连接超时。最大连接数不是越大越好,连接要占数据库内存,每个连接也要开销;超过数据库能承受的连接数反而让整体变慢。核心经验是最大连接数按数据库实例规格与并发预估来定,超时时间避免请求无限等下去。
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000
池满之后新请求要排队等连接,等待超时抛异常。所以参数之间是联动的:池太小请求排队,池太大数据库扛不住,要压测找到平衡点。
HikariCP 参数调优
HikariCP 的调优围绕几个点:maximumPoolSize 决定并发上限,connectionTimeout 决定等待上限,maxLifetime 控制连接最大存活时间,idleTimeout 控制空闲回收。数据库会清理超时连接,连接池的连接要小于数据库的 wait_timeout,否则连接被库端断开后池里还留着,取出来就报错。
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.validation-timeout=3000
连接池会自动检测失效连接:取连接时校验可用性,定期发送测试查询。校验频率过高会白白增加数据库负载,一般让池的主动校验兜底即可。
连接泄漏与监控
最常见的故障是连接泄漏:代码里开了连接忘记关闭,池里的连接被借光,后续请求全部等超时。框架一般会在连接归还时做泄漏检测,也可以开启连接借出超时记录,把长时间未归还的连接打日志。监控上要盯连接池的几个指标:活跃连接数、池待获取数、等待超时次数。
// 用 try-with-resources 保证归还
try (Connection conn = ds.getConnection()) {
// 业务逻辑
} // 自动关闭归还
线上告警阈值建议:池使用率达到百分之八十持续一段时间就报警,等到百分之百再处理往往已经出现超时。
高并发下的连接治理
高并发下连接池会成为瓶颈,治理方向有三条:减少连接占用时间,把慢查询与长事务改掉,事务里别做网络请求;给不同业务分池,读写分离、接口拆分,避免一个慢业务把公共池占满;用缓存挡掉一部分读流量,减少对数据库的访问。
- 压缩占用改慢查询与长事务。
- 隔离分池分库,故障不蔓延。
- 削峰缓存与队列挡掉重复读。
连接池参数不是一次调完就完事,要跟着容量评估与压测结果滚动调整,每轮发版前做一次连接池容量核对。
读写分离与多数据源
读写分离场景下,主库与从库各配一个连接池,读多写少的业务把读流量导向从库池,主库池压力大幅下降。多数据源要注意事务边界:跨库事务要谨慎,尽量按业务把写操作收敛到主库,别让一次请求串两个事务。
spring.datasource.master.hikari.maximum-pool-size=20
spring.datasource.slave.hikari.maximum-pool-size=50
从库有复制延迟,读从库的接口要接受短暂不一致;一致性要求高的读仍走主库,或者用读写分离中间件按规则路由。
常见故障排查
连接池相关故障有规律可循。报连接获取超时:先看池使用率,满则查泄漏与慢查询;报连接被关闭:查数据库 wait_timeout 与池 maxLifetime 是否匹配;报连接拒绝:查数据库连接数上限与实例规格。排查先看监控曲线,再抓现场日志,别一上来就改参数。
-- 数据库侧查看当前连接
SHOW STATUS LIKE 'Threads_connected';
SHOW PROCESSLIST;
故障记录要沉淀成文档,每次事故复盘把根因、排查路径、处置动作写清楚,同类问题下次直接照单排查。
落地清单
- 连接池参数按并发压测定,别拍脑袋。
- 最大连接数要小于数据库可承受上限。
- 连接存活时间与数据库 wait_timeout 匹配。
- 代码用自动关闭模式,杜绝泄漏。
- 监控活跃数、等待超时与池使用率。
- 高并发用分池隔离与缓存削峰。