连接从哪里来:连接池原理

每次访问数据库都新建连接,握手、鉴权、建立会话的开销不小,高并发下连接一多数据库就被拖垮。连接池的思路是预先建好一批连接放在池里,应用借了用完再还,连接复用省掉反复建连。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()) {
  // 业务逻辑
} // 自动关闭归还

线上告警阈值建议:池使用率达到百分之八十持续一段时间就报警,等到百分之百再处理往往已经出现超时。