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

1次阅读

mysql连接数超限表现为too many connections错误或连接拒绝/超时,主因是连接未释放、池配置不当或短连接滥用;需协同调优hikaricp参数(maximumpoolsize、idletimeout等)、mysql参数(wait_timeout、max_connections等)并排查泄漏。

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

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 resetCommunications link failure

  • wait_timeoutinteractive_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=SleepTime > 300 的连接,结合 Info 列(如果非 NULL)判断是哪类查询残留
  • 检查代码中所有 ConnectionPreparedStatementResultSet 是否都在 finally 块或 try-with-resources 中显式关闭;JDBC 4.0+ 后者更可靠

MySQL 连接问题很少是单点故障,往往是池配置、服务端参数、代码习惯三者叠加出的问题。最容易被忽略的是 wait_timeoutidleTimeout 的数值错位,以及没有开启连接泄漏检测。

text=ZqhQzanResources