连接池核心参数:一次讲透

连接池的参数,说多不多,说少不少。
很多新同学跑了个 demo,发现默认配置能用,就不管了。
结果线上流量一上来,数据库直接被打穿。

我自己之前维护过一个内部报表系统,每天凌晨定时跑任务。
某天突然报警:数据库连接数飙到 2000+,DBA 差点杀我。
查了半天,原来是最小连接数设得太高,空闲连接把 pool 撑爆了。

所以这几个参数,真的得搞明白。咱一个一个看。

最小连接数(minimum-idle / minPoolSize)

最小连接数,说白了就是连接池里始终保留的最少连接数。
哪怕没人用,也要挂着。

为什么要设这个?
因为建立连接太慢了。TCP 三次握手 + MySQL 鉴权,一次可能几百毫秒。
如果请求突然来了,再临时建连接,响应时间直接炸。

我在项目中遇到过一个场景:
某个服务每天上午 10 点定时触发流量高峰,那时候数据库负载瞬间上升。
我建议把最小连接数提到 10,这样高峰来临时连接已经是现成的,响应时间从 2 秒降到 200 毫秒。

我的习惯:最小连接数不要设太高。
一般按服务正常空闲流量来定。如果是定时任务型服务,可以动态调大,闲时再缩回去。

最大连接数(maximum-pool-size / maxPoolSize)

这就是连接池允许的最大连接数。
超过这个数,新的请求就会排队或报错。

为什么会有限制?
因为数据库本身也有连接上限。比如 MySQL 默认 151,调太高可能把服务器搞挂。

踩坑案例:我曾经给一个微服务把最大连接数设成 300,觉得越多越好。
结果数据库 CPU 直接 100%,连接全部卡死。
后面才发现,数据库端的 max_connections 只设了 200,多出来的连接都在握手状态堆积。

一般建议:最大连接数 ≤ 数据库 max_connections × 0.7,留点余量给管理工具。
大多数应用 20~50 就够用了。除非你并发特别高,才需要 100+。

最大空闲时间(idleTimeout / maxIdleTime)

连接空闲超过这个时间,就会被回收。
说白了就是连接池帮你自动清理“吃饭不干活”的连接。

我见过一个项目把空闲时间设成 0(永不超时)。
结果服务器一跑几个月,连接数慢慢泄漏,最后 OOM。其实很多连接早就被数据库主动断掉了,但 pool 里还留着误以为可用,下次请求直接拿到坏连接。

我个人建议:
根据数据库的 wait_timeout 来设。比如 MySQL 默认 8 小时,那你设个 5 分钟就挺合理。
这样即使连接被数据库提前关闭,pool 也能及时清理掉。

参数默认值(常见)我的推荐范围说人话
最小连接数0 ~ 52 ~ 10闲着也得养几个兵
最大连接数10 ~ 2020 ~ 50(一般服务)别挤爆数据库
最大空闲时间60s ~ 300s60s ~ 300s不干活就滚蛋
连接超时30s3s ~ 10s等太久直接放弃

连接超时(connectionTimeout / connectTimeout)

这个参数控制:向连接池申请连接时,最多等多久。
超时了就抛异常,不让你死等。

很多同学会问:超时时间设长点不行吗?
设长了,用户请求卡住几十秒,体验极差。
而且连接池的线程也会被占着,慢慢拖垮整个服务。

我见过最离谱的配置:连接超时设了 300 秒。
一次数据库主从切换,连接池全部线程在等连接,所有请求排队 5 分钟才报错。
网关都扛不住,直接把服务熔断了。

我个人习惯:
普通业务 API 连接超时设 3~5 秒,后台批量任务可以放宽到 10~15 秒。
别超过 30 秒,除非你对数据库延迟有十足把握。

核心参数的相互关系

这几个参数不是孤立的,它们共同决定了连接池的行为。
下面这张图可以帮你理清整体逻辑:

连接池核心参数关系图 连接池(HikariCP / DBCP / Druid) 最小连接数 minPoolSize / minimum-idle 最大连接数 maxPoolSize / maximum-pool-size 最大空闲时间 idleTimeout / maxIdleTime 连接超时 connectionTimeout 保证下限 回收多余 触发回收 等待上限 外部请求 数据库 实际连接

从图上可以看到:

  • 最小连接数像是“底仓”,保证基本够用
  • 最大连接数是“天花板”,防止滥用
  • 空闲时间用来清理不干活的多余连接,把池子压回接近最小连接数
  • 连接超时控制申请连接的耐心,超时就报错,不让请求死等

总结一下配置原则

我个人的配置清单(以 HikariCP 为例,JDBC 连接 MySQL):

spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.idle-timeout=120000
spring.datasource.hikari.connection-timeout=5000
  1. 最小连接数 5:空闲时保持 5 个连接,够日常突发
  2. 最大连接数 30:数据库 max_connections 设为 100,留 70 给其他服务和管理
  3. 空闲时间 120 秒:让连接在空闲 2 分钟后被回收
  4. 连接超时 5 秒:请求能接受的等待上限
特别提醒:不同数据库、不同连接池的默认值差别很大。
HikariCP 的 idleTimeout 默认是 10 分钟,而 C3P0 的 maxIdleTime 默认是 0(永不过期)。
切换连接池时,一定要重新审视这些参数。

嗯,核心参数就这些。
一开始会觉得参数多,其实每一个都有明确的用途。
你按上面的思路调一遍,基本不会出大问题。