连接池设计

数据库与下游连接复用开销高,需要连接池:池大小按并发与下游容量核算,超时要覆盖取连接与执行两个阶段,避免取连接排队拖垮整条链路。

连接池设计是什么

建立数据库或下游连接的开销远大于执行一次请求,因此需要连接池复用。池大小要同时满足两个约束:不超过应用侧需要的并发上限,也不超过下游能够承载的连接数;池设得过大,会把压力直接转成下游的连接拒绝或排队。超时同样要覆盖两个阶段——等待获取连接与执行请求,只设执行超时会让请求大量阻塞在取连接阶段,表现出来就是「数据库显示空闲,应用却全部超时」。

基本信息

池大小按应用并发上限与下游可承载连接数综合确定
取连接超时单独设置且计入端到端延迟预算
空闲回收空闲连接释放时间应短于下游主动断开的时间
连接寿命设置最大存活时间,与下游超时错开避免复用到失效连接
泄漏检测记录借用超时的调用栈,定位未归还连接的代码

典型使用场景

  • 数据库访问:应用与数据库之间的连接复用,最常见的场景
  • HTTP 下游调用:对第三方接口保持长连接,减少握手开销
  • 缓存客户端:与缓存集群的连接复用与故障重建
  • 消息客户端:生产者与消费者的连接与信道管理
  • 批量任务:离线任务单独配置池,避免占用在线连接额度
  • 多租户隔离:为不同租户或业务划分独立池,限制相互影响

配置要点

配置要点
# 池大小:max_pool = min(应用并发需求, 下游可承载连接数 / 实例数)
# 取连接超时:单独设置(如 1s),并计入端到端延迟预算
# 执行超时:与取连接超时分开配置,避免混淆排队与执行耗时
# 空闲回收:idle_timeout 短于下游主动断开连接的阈值
# 连接寿命:max_lifetime 小于下游超时,避免复用到已被关闭的连接
# 泄漏检测:借用超过阈值打印调用栈并告警,定位未归还连接的地方

参数清单

参数作用配置要点
池大小上限同时借出的连接数上限按并发与下游连接上限反推,不要凭感觉加大
取连接超时等待借出的时间上限单独设置并计入端到端预算
空闲回收长时间空闲连接释放短于下游主动断开的时间
连接寿命上限连接重建周期与下游超时错开,避免复用到失效连接
泄漏检测借用超时告警记录疑似泄漏的调用栈
池大小超过下游承载能力时会转化为排队等待:连接池解决的是复用与复用成本,不能凭空扩容下游,调大池往往只是把问题从应用挪到数据库。
多实例部署时按实例数计算总连接数:单实例池 50、部署 20 个实例,对数据库就是 1000 个连接,很容易超过数据库上限。

易错点

  • 池设置过大:总连接数超过数据库上限,出现连接拒绝或内存压力
  • 等待连接无超时:请求全部阻塞在取连接阶段,故障表现被误判
  • 只设执行超时不设取连接超时:排队时间不计入监控,延迟黑盒
  • 连接寿命与下游超时不匹配:复用到已被服务端关闭的连接,偶发报错
  • 多实例未核算总连接数:单实例配置合理,整体部署后压垮数据库

数据来源与参考

  • HikariCP 文档:About Pool Sizing
  • 《性能之巅(第 2 版)》(Gregg)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌