深色模式
数据库连接池配置
摘要:连接池配置不当是「数据库被打满」的头号原因。本文给出 HikariCP(Java)与 Druid 的关键参数、连接数计算方法,以及连接泄漏与超时的排查手段。
适用环境
bash
# 先看数据库侧最大连接与当前使用
mysql -uroot -p -e "SHOW VARIABLES LIKE 'max_connections'; SHOW GLOBAL STATUS LIKE 'Threads_connected';"
# 应用侧确认有几个实例(Pod/节点数)
kubectl get pod -l app=order -o wide 2>/dev/null | wc -l1
2
3
4
2
3
4
操作步骤
1. 最大连接数怎么算
单应用最大连接数 ≈ 数据库 max_connections × 0.8 / 应用实例数1
例:数据库 max_connections=500,应用 10 个实例 → 每实例不超过 40。
危险
每个实例都配 maximumPoolSize=100、开 50 个实例就是 5000 个连接,远超数据库承载能力,会直接把数据库打挂。扩容应用节点时必须同步下调单节点池大小。
2. HikariCP 配置(Spring Boot)
yaml
spring:
datasource:
hikari:
maximum-pool-size: 20 # 核心参数,按上面公式算
minimum-idle: 5
connection-timeout: 3000 # 拿不到连接最多等 3 秒,快速失败
idle-timeout: 600000
max-lifetime: 1500000 # 必须小于数据库 wait_timeout
validation-timeout: 3000
leak-detection-threshold: 60000 # 超过 60 秒未归还即打印堆栈,定位泄漏1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
3. Druid 配置
yaml
spring:
datasource:
druid:
initial-size: 5
max-active: 20
min-idle: 5
max-wait: 3000 # 获取连接最大等待毫秒
test-while-idle: true
validation-query: SELECT 1
time-between-eviction-runs-millis: 60000
remove-abandoned: true # 回收泄漏连接(谨慎,见常见坑)
remove-abandoned-timeout: 1801
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
4. 超时三件套
| 参数 | 作用 | 建议 |
|---|---|---|
| connectTimeout | 建立 TCP 连接 | 3~5 秒 |
| socketTimeout | 等待查询结果 | 按接口超时设定,如 10 秒 |
| 事务超时 | 限制长事务 | 明显小于 socketTimeout |
sql
-- MySQL 侧限制单条查询时长(只读 SELECT)
SET SESSION max_execution_time = 5000; -- 毫秒1
2
2
5. 排查连接泄漏
sql
-- MySQL:找出长时间 sleep 或处于事务中的连接
SELECT id, user, host, db, command, time, state, LEFT(info, 60)
FROM information_schema.processlist
WHERE time > 60 ORDER BY time DESC LIMIT 20;
-- 统计各账号连接数
SELECT user, count(*) FROM information_schema.processlist GROUP BY user;1
2
3
4
5
6
7
2
3
4
5
6
7
bash
# 观察应用日志中 HikariPool 关键字
grep -i 'HikariPool' app.log | tail -n 20
# "Connection is not available, request timed out" 说明池不够或有泄漏1
2
3
2
3
验证
- [ ] 压测时数据库连接数稳定在池上限内,不出现
Too many connections - [ ] 应用日志无
HikariPool超时与leak detection告警 - [ ] 数据库侧
Threads_connected远小于max_connections - [ ] 手动断开网络后,连接能在
connection-timeout内失败并恢复
常见坑
WARNING
max-lifetime 大于数据库 wait_timeout 会导致应用拿到已被服务端关闭的连接,报 Communications link failure;两者要留出余量。
WARNING
Druid 的 remove-abandoned 会强制回收超时连接,若存在正常慢查询会被误杀并报连接已关闭,生产建议先关闭,用 leak-detection-threshold 之类手段定位后再开。
DANGER
连接池不是越大越好:MySQL 连接数与吞吐在超过一定并发后反而下降(上下文切换、锁争用),盲目调大只会加速雪崩。