F
Member
应用一繁忙就“数据库连接数爆了”,多半不是业务 SQL 突然变多这么简单,而是连接生命周期没管好。连接池存在的理由,首先是建连贵,其次是数据库侧有硬上限。
一、建连不只是 TCP 握手
一次数据库连接通常包含网络握手、认证、会话初始化、时区与字符集等设置,开销远高于从池里借出一条已有连接。短连接模式下,每次请求新建再销毁,CPU 与延迟都会被握手吃掉,数据库进程/线程也会被频繁创建销毁拖累。连接池把连接复用起来,让请求只付“借用与归还”的成本。
二、数量上限与排队
数据库有 max_connections 一类上限,操作系统与内存也限制得住多少会话。应用实例再乘线程模型,很容易在峰值把库打满。池子通过设置最大连接数、等待超时、空闲回收,把压力挡在应用侧:该排队排队,该失败失败,避免把数据库拖进连接风暴。微服务多实例时,更要按“实例数 × 每池上限”总和做容量规划。
三、泄漏比“池太小”更常见
连接借出后未归还(异常路径忘记 close、事务挂起、异步回调丢失),池会逐渐耗尽,表现为偶发获取连接超时。排查要看池监控:活跃数、等待数、泄漏检测栈。也要避免在池连接上做超长业务(远程调用、人工确认),把连接占用时间拉长等价于缩小池子。只调大 max_connections 而不治理泄漏与慢 SQL,往往会把问题推迟成更猛的雪崩。
连接池参数应写进容量规划文档,并与数据库侧上限、代理层限制一起评审。
在 Serverless 或弹性扩容场景,冷启动瞬间的建连尖峰尤其需要限流与池预热策略。
讨论问题:
1. 你们每实例连接池上限怎么估?有没有按只读实例拆分?
2. 连接泄漏最有效的发现手段是监控报警还是定期强制回收?
3. 高峰期更常见的是池耗尽,还是数据库本身 CPU/IO 先满?
一、建连不只是 TCP 握手
一次数据库连接通常包含网络握手、认证、会话初始化、时区与字符集等设置,开销远高于从池里借出一条已有连接。短连接模式下,每次请求新建再销毁,CPU 与延迟都会被握手吃掉,数据库进程/线程也会被频繁创建销毁拖累。连接池把连接复用起来,让请求只付“借用与归还”的成本。
二、数量上限与排队
数据库有 max_connections 一类上限,操作系统与内存也限制得住多少会话。应用实例再乘线程模型,很容易在峰值把库打满。池子通过设置最大连接数、等待超时、空闲回收,把压力挡在应用侧:该排队排队,该失败失败,避免把数据库拖进连接风暴。微服务多实例时,更要按“实例数 × 每池上限”总和做容量规划。
三、泄漏比“池太小”更常见
连接借出后未归还(异常路径忘记 close、事务挂起、异步回调丢失),池会逐渐耗尽,表现为偶发获取连接超时。排查要看池监控:活跃数、等待数、泄漏检测栈。也要避免在池连接上做超长业务(远程调用、人工确认),把连接占用时间拉长等价于缩小池子。只调大 max_connections 而不治理泄漏与慢 SQL,往往会把问题推迟成更猛的雪崩。
连接池参数应写进容量规划文档,并与数据库侧上限、代理层限制一起评审。
在 Serverless 或弹性扩容场景,冷启动瞬间的建连尖峰尤其需要限流与池预热策略。
讨论问题:
1. 你们每实例连接池上限怎么估?有没有按只读实例拆分?
2. 连接泄漏最有效的发现手段是监控报警还是定期强制回收?
3. 高峰期更常见的是池耗尽,还是数据库本身 CPU/IO 先满?