连接池核心参数:一次讲透
连接池的参数,说多不多,说少不少。
很多新同学跑了个 demo,发现默认配置能用,就不管了。
结果线上流量一上来,数据库直接被打穿。
我自己之前维护过一个内部报表系统,每天凌晨定时跑任务。
某天突然报警:数据库连接数飙到 2000+,DBA 差点杀我。
查了半天,原来是最小连接数设得太高,空闲连接把 pool 撑爆了。
所以这几个参数,真的得搞明白。咱一个一个看。
最小连接数(minimum-idle / minPoolSize)
最小连接数,说白了就是连接池里始终保留的最少连接数。
哪怕没人用,也要挂着。
为什么要设这个?
因为建立连接太慢了。TCP 三次握手 + MySQL 鉴权,一次可能几百毫秒。
如果请求突然来了,再临时建连接,响应时间直接炸。
我在项目中遇到过一个场景:
某个服务每天上午 10 点定时触发流量高峰,那时候数据库负载瞬间上升。
我建议把最小连接数提到 10,这样高峰来临时连接已经是现成的,响应时间从 2 秒降到 200 毫秒。
一般按服务正常空闲流量来定。如果是定时任务型服务,可以动态调大,闲时再缩回去。
最大连接数(maximum-pool-size / maxPoolSize)
这就是连接池允许的最大连接数。
超过这个数,新的请求就会排队或报错。
为什么会有限制?
因为数据库本身也有连接上限。比如 MySQL 默认 151,调太高可能把服务器搞挂。
结果数据库 CPU 直接 100%,连接全部卡死。
后面才发现,数据库端的 max_connections 只设了 200,多出来的连接都在握手状态堆积。
一般建议:最大连接数 ≤ 数据库 max_connections × 0.7,留点余量给管理工具。
大多数应用 20~50 就够用了。除非你并发特别高,才需要 100+。
最大空闲时间(idleTimeout / maxIdleTime)
连接空闲超过这个时间,就会被回收。
说白了就是连接池帮你自动清理“吃饭不干活”的连接。
我见过一个项目把空闲时间设成 0(永不超时)。
结果服务器一跑几个月,连接数慢慢泄漏,最后 OOM。其实很多连接早就被数据库主动断掉了,但 pool 里还留着误以为可用,下次请求直接拿到坏连接。
我个人建议:
根据数据库的 wait_timeout 来设。比如 MySQL 默认 8 小时,那你设个 5 分钟就挺合理。
这样即使连接被数据库提前关闭,pool 也能及时清理掉。
| 参数 | 默认值(常见) | 我的推荐范围 | 说人话 |
|---|---|---|---|
| 最小连接数 | 0 ~ 5 | 2 ~ 10 | 闲着也得养几个兵 |
| 最大连接数 | 10 ~ 20 | 20 ~ 50(一般服务) | 别挤爆数据库 |
| 最大空闲时间 | 60s ~ 300s | 60s ~ 300s | 不干活就滚蛋 |
| 连接超时 | 30s | 3s ~ 10s | 等太久直接放弃 |
连接超时(connectionTimeout / connectTimeout)
这个参数控制:向连接池申请连接时,最多等多久。
超时了就抛异常,不让你死等。
很多同学会问:超时时间设长点不行吗?
设长了,用户请求卡住几十秒,体验极差。
而且连接池的线程也会被占着,慢慢拖垮整个服务。
一次数据库主从切换,连接池全部线程在等连接,所有请求排队 5 分钟才报错。
网关都扛不住,直接把服务熔断了。
我个人习惯:
普通业务 API 连接超时设 3~5 秒,后台批量任务可以放宽到 10~15 秒。
别超过 30 秒,除非你对数据库延迟有十足把握。
核心参数的相互关系
这几个参数不是孤立的,它们共同决定了连接池的行为。
下面这张图可以帮你理清整体逻辑:
从图上可以看到:
- 最小连接数像是“底仓”,保证基本够用
- 最大连接数是“天花板”,防止滥用
- 空闲时间用来清理不干活的多余连接,把池子压回接近最小连接数
- 连接超时控制申请连接的耐心,超时就报错,不让请求死等
总结一下配置原则
我个人的配置清单(以 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
- 最小连接数 5:空闲时保持 5 个连接,够日常突发
- 最大连接数 30:数据库 max_connections 设为 100,留 70 给其他服务和管理
- 空闲时间 120 秒:让连接在空闲 2 分钟后被回收
- 连接超时 5 秒:请求能接受的等待上限
HikariCP 的
idleTimeout 默认是 10 分钟,而 C3P0 的 maxIdleTime 默认是 0(永不过期)。切换连接池时,一定要重新审视这些参数。
嗯,核心参数就这些。
一开始会觉得参数多,其实每一个都有明确的用途。
你按上面的思路调一遍,基本不会出大问题。