mysql连接数过多怎么办_mysql连接池配置

来源:这里教程网 时间:2026-02-28 20:51:05 作者:

MySQL 连接数超限的典型表现

看到

Too many connections
错误,或应用日志里频繁出现连接拒绝、超时,基本可以确认是 MySQL 的最大连接数被耗尽。这不一定是业务量暴增导致的,更常见的是连接未正确释放、连接池配置失当、或短连接滥用。

max_connections
是 MySQL 服务端硬限制,默认通常为 151(MySQL 5.7+),可通过
SHOW VARIABLES LIKE 'max_connections';
查看
实际活跃连接数可查
SHOW STATUS LIKE 'Threads_connected';
,注意它包含空闲连接,不代表都在干活
真正危险的是
Threads_running
持续偏高,说明有大量查询在排队或阻塞

Java 应用中 HikariCP 连接池关键配置项

HikariCP 是目前最主流的 JDBC 连接池,它的默认行为对 MySQL 很友好,但若不做调整,极易因“保守”或“激进”引发问题。

maximumPoolSize
:不要盲目设成 100 或 200。建议初始值设为
2 × (CPU 核数) + 1
,再根据压测中
Threads_running
和应用 RT 调整
minimumIdle
:设为与
maximumPoolSize
相同(即固定大小池),可避免动态扩缩带来的抖动;但若应用流量波峰波谷明显,可设为
maximumPoolSize × 0.3
connectionTimeout
:建议 30000(30 秒),太短会让业务误报失败,太长会拖垮线程池
idleTimeout
:MySQL 默认
wait_timeout=28800
(8 小时),HikariCP 的
idleTimeout
必须小于它,否则连接可能被 MySQL 主动断开后,池子还傻等——推荐设为 10 分钟(600000)
keepaliveTime
:仅在
minimumIdle  时生效,用于定期探测空闲连接是否存活,设为 300000(5 分钟)较稳妥  

MySQL 侧必须同步调整的几个参数

光调应用层没用,MySQL 本身也得配合。否则连接池以为连接还活着,MySQL 却已悄悄关掉,结果就是

Connection reset
Communications link failure

wait_timeout
interactive_timeout
必须一致,且建议设为 600(10 分钟)或 1800(30 分钟),不能留默认 8 小时
max_connections
不宜设得过高(比如 5000)。每个连接至少占用 256KB 内存,上万连接可能直接吃光服务器内存;应优先优化单连接效率和池复用率
开启
skip_name_resolve
:避免 DNS 反查拖慢连接建立,尤其在容器或云环境里特别明显
检查是否有长期未关闭的
SLEEP
状态连接:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 60;
—— 找出源头代码里的漏掉
close()
的地方

排查连接泄漏的实操路径

连接数缓慢上涨、重启后回落,大概率是泄漏。别只盯着连接池配置。

在应用启动时开启 HikariCP 的 debug 日志:
logging.level.com.zaxxer.hikari=DEBUG
,重点看
Connection leak detection
相关输出
使用
leakDetectionThreshold
(单位毫秒),例如设为 60000(1 分钟),一旦连接被借出超过该时间未归还,HikariCP 会打印堆栈
数据库侧执行
SHOW PROCESSLIST;
,按
TIME
倒序,重点关注
Command=Sleep
Time > 300
的连接,结合
Info
列(如果非 NULL)判断是哪类查询残留
检查代码中所有
Connection
PreparedStatement
ResultSet
是否都在
finally
块或 try-with-resources 中显式关闭;JDBC 4.0+ 后者更可靠

MySQL 连接问题很少是单点故障,往往是池配置、服务端参数、代码习惯三者叠加出的问题。最容易被忽略的是

wait_timeout
idleTimeout
的数值错位,以及没有开启连接泄漏检测。

相关推荐