maxlifetime必须严格小于mysql的wait_timeout,建议至少小30秒,如wait_timeout=3600秒则设max-lifetime=3500000毫秒,避免连接池复用已被服务端关闭的连接而抛出communications link failure等异常。

maxLifetime 必须比 MySQL 的 wait_timeout 小至少 30 秒
连接池不会等 MySQL 主动断开连接后再处理,而是要提前“退休”掉老连接。如果 maxLifetime ≥ wait_timeout,连接池可能把一个已被 MySQL 关闭的连接再分配出去,下一次执行 SQL 就直接抛 Communications link failure 或 MySQL server has gone away。
查 MySQL 当前设置:SHOW VARIABLES LIKE 'wait_timeout';,假设返回 3600(1 小时),那么 HikariCP 应设:max-lifetime: 3500000(58 分 20 秒);Druid 对应 maxEvictableIdleTimeMillis 同理。
- 别设为 0(永不过期),生产环境禁止
- 云数据库(如阿里云 RDS)常把
wait_timeout改成 1800 或 900,你要按它的真实值来配,不是默认值 - 若无法确认服务端值,保守起见统一设
maxLifetime = 1800000(30 分钟)
idleTimeout 不是最大空闲时间,别和 maxLifetime 混用
idleTimeout 控制的是连接在池中“空闲多久没被借走”就回收,而 maxLifetime 控制的是“从创建起总共活多久”。前者防堆积,后者防被 MySQL 踢。
例如 HikariCP 中:idleTimeout: 600000(10 分钟)表示空闲超 10 分钟就清理;maxLifetime: 3500000(58 分 20 秒)确保哪怕一直被频繁借用,也活不过 58 分 20 秒。
- 两者都要设,但作用不同:一个管“冷连接”,一个管“老连接”
-
idleTimeout默认是 600000(10 分钟),可接受;但maxLifetime默认 1800000(30 分钟)可能仍大于你的wait_timeout,必须显式覆盖 - Druid 的
minEvictableIdleTimeMillis类似idleTimeout,别误当成maxLifetime的替代
Node.js mysql2 连接池怎么设 idleTimeoutMillis?
mysql2 的 createPool 没有 maxLifetime 参数,靠 idleTimeoutMillis 实现类似效果——它实际承担了“最大连接寿命”的职责,因为 mysql2 不维护连接创建时间戳,只能靠空闲期兜底。
配置示例:
const pool = mysql.createPool({<br> host: 'localhost',<br> user: 'root',<br> database: 'test',<br> idleTimeoutMillis: 3500000,<br> waitForConnections: true,<br> queueLimit: 0<br>});
-
idleTimeoutMillis是 mysql2 唯一能控制连接“主动退休”的参数,必须设,不能依赖默认值(10000ms) - 它应严格小于 MySQL 的
wait_timeout,留出至少 60 秒缓冲 - 别配
ping()定时保活:多余、低效、掩盖配置问题
验证连接是否真被池子提前回收了?
光看配置没用,得验证连接池是否真的在 MySQL 断开前就销毁了连接。最直接方式是抓包或开 MySQL general_log,但更实用的是观察 SHOW PROCESSLIST 中连接的 Time 字段。
如果池子生效,你会看到连接的 Time 值很少超过 maxLifetime / 1000 - 30 秒;如果大量连接 Time 接近 wait_timeout,说明池子没起作用。
- 注意区分:事务未提交时
Time不增长,maxLifetime仍会计时(HikariCP 等会强制关闭) - Druid 的日志里搜
abandon,HikariCP 看HikariPool-1 - Pool stats中的alive时间 - 最容易忽略的一点:Spring Boot 自动配置可能覆盖你写的
max-lifetime,务必检查最终生效的配置(用/actuator/env)











