连接池核心参数:最小空闲连接数、最大连接数、连接超时时间

连接池调优,说白了就是跟三个数字打交道:最小空闲连接数、最大连接数、连接超时时间。这三个参数就像发动机的油门、刹车和限速器——调得好,系统丝滑;调不好,要么卡死,要么浪费资源。

我个人习惯先把它们拆开理解,再合起来看联动关系。咱们一个一个说。

最小空闲连接数(minimumIdle)

这个参数控制连接池“闲时”保留多少连接。比如设成5,那不管有没有请求,池子里至少躺着5个可用连接。好处是——突然来流量时不用现场创建连接,直接拿现成的,响应快。

但别设太大。我在项目中遇到过一个小型后台服务,minimumIdle 设了50,结果服务刚启动就一口气创建50个连接。数据库那边直接报警了——你想想看,一个平时只有20并发的小应用,让50个连接占着坑,那不是浪费么?

我的经验值:并发平稳的服务,minimumIdle 设成 maximumPoolSize 的 20%~30% 就够了。突发流量多的场景,可以适当提高到 40%,但不要超过一半。

最大连接数(maximumPoolSize)

这个参数就是连接池的“天花板”。池子里能同时存在的连接数不能超过这个值。设小了,请求排队;设大了,数据库扛不住。

我记得有一次帮朋友优化一个电商订单系统。他们数据库是 4 核 8G 的 MySQL,连接池最大连接数直接拉了 200。上线没两天,数据库 CPU 跑满,慢查询一堆。我一看配置就知道出事了——MySQL 的默认连接数是 151,你把池子开到 200,数据库本身还有后台线程、复制线程,实际能用的连接数远少于理论值。

数据库规格 建议最大连接数 备注
4核8G MySQL 30~60 不超过数据库 max_connections 的 60%
8核16G MySQL 50~120 按连接平均消耗 2~3MB 算
2核4G PostgreSQL 20~40 PG 每个连接开销更大

你可能会问:那怎么算才准?我建议用这个简单公式:最大连接数 = (数据库 CPU 核心数 × 2) + 预留缓冲。预留缓冲通常加 10~20 就够,别搞太大。

避坑指南:我曾经接手过一个项目,maximumPoolSize 设了 80,但应用实际并发只有 10 左右。结果就是连接池里 70 个连接常年闲着,占着数据库的连接配额,导致其他服务连不上。你想想看,浪费钱不说,还制造故障。

连接超时时间(connectionTimeout)

这个参数定义了:等一个连接最多等多久。如果池子里没有空闲连接了,请求线程会阻塞。超过这个时间,就抛异常。

设太短,比如 1 秒,流量波峰时大量请求被直接拒绝,用户体验极差。设太长,比如 60 秒,线程会一直卡在那边,拖慢整个应用。

我以前在支付系统里遇到过一个问题:connectionTimeout 设了 30 秒,结果某次数据库主从切换时,所有获取连接的线程都阻塞在那 30 秒,Tomcat 线程池被占满,整个服务变成“假死”。

// HikariCP 配置示例
HikariConfig config = new HikariConfig();
config.setMinimumIdle(10);
config.setMaximumPoolSize(50);
config.setConnectionTimeout(5000); // 毫秒,推荐 3~10 秒
config.setIdleTimeout(600000);     // 10分钟
config.setMaxLifetime(1800000);    // 30分钟
我建议:内部调用系统(低延迟要求)设 3~5 秒;面向用户的 API 可以放宽到 8~10 秒。但千万别超过 15 秒——用户等不了那么久,还不如直接返回友好错误。

三个参数如何协同工作

这三个参数不是孤立的。它们构成一个动态平衡系统:minimumIdle 决定了“保底库存”,maximumPoolSize 划定了“上限”,connectionTimeout 控制了“等待耐心”。当请求量超过 minimumIdle 时,池子会动态创建新连接,直到到达 maximumPoolSize。如果继续超载,请求就进入等待队列,直到超过 connectionTimeout 才抛出异常。

连接池核心参数协同流程图 请求到来 检查空闲连接 有空闲连接 → 直接分配 无空闲 / 已达 minimumIdle 创建新连接 已达 maximumPoolSize 等待连接 → 超时 {connectionTimeout} 调优要点 minimumIdle 保底 maximumPoolSize 封顶 connectionTimeout 控等待

核心要点:

  • minimumIdle 不要超过 maximumPoolSize 的 40%,否则浪费。
  • maximumPoolSize 要参考数据库规格,别凭感觉设。
  • connectionTimeout 建议 3~8 秒,别让线程死等。
  • 三个参数联动:空闲不够→创建→触顶→等待→超时。

调优小技巧:先压测,看平均响应时间和并发峰值。比如压测时平均 50 并发,那就把 minimumIdle 设 15~20,maximumPoolSize 设 60~80。再观察数据库 CPU 和连接数,微调两三回就能找到最佳点。

常见陷阱:

  • 陷阱一:maximumPoolSize 设得比数据库 max_connections 还大,直接连不上。
  • 陷阱二:connectionTimeout 设成 0(表示无限等待),系统扛不住突发流量时会一直阻塞,最终 OOM。
  • 陷阱三:minimumIdle 和 maximumPoolSize 设成一样,等同禁止扩容,失去了连接池的意义。