MySQL连接池需合理设置最大连接数以匹配业务并发与数据库承载能力,避免盲目调高导致资源耗尽;应基于压测结果计算并留余量,同步调整MySQL的max_connections;启用空闲连接回收与保活机制;确保事务边界与连接生命周期对齐;持续监控动态调优。

MySQL连接池的核心目标是减少频繁创建和销毁连接的开销,同时避免连接数过多导致数据库资源耗尽。关键不在“越多越好”,而在于匹配业务并发特征与数据库承载能力。
合理设置最大连接数(maxActive / maxPoolSize)
盲目调高最大连接数反而会拖垮数据库:每个MySQL连接占用内存(约2-3MB),且线程调度、锁竞争随连接数上升而加剧。应基于实际压测结果设定:
- 参考公式:最大连接数 ≈ (平均单次SQL耗时 × 预估QPS)/ 0.8,再向上取整并留20%余量
- MySQL服务端需同步检查 max_connections 值是否足够,建议设为应用连接池最大值的1.2–1.5倍
- 例如:QPS为500,平均查询耗时80ms,则理论最小连接需求 ≈ (0.08 × 500) / 0.8 = 50,可设连接池 maxPoolSize = 60
启用空闲连接回收与保活机制
长时间空闲的连接可能被中间网络设备(如防火墙、负载均衡器)或MySQL自身(wait_timeout)强制断开,导致应用获取到“假活跃”连接而报错。
- 开启 testOnBorrow(借出前检测)或更推荐的 testWhileIdle(空闲时检测),配合 validationQuery="SELECT 1"
- 设置 minEvictableIdleTimeMillis(如30000ms),确保空闲超30秒的连接被清理
- 配置 timeBetweenEvictionRunsMillis(如60000ms),让空闲检测线程每分钟运行一次
复用连接的关键:事务边界与连接生命周期对齐
连接复用失效常因代码未正确释放连接,或在事务中跨方法传递Connection对象导致泄漏。
- 务必使用 try-with-resources 或 finally 显式 close(),即使使用了Spring @Transactional,也要确认AOP代理生效且未绕过连接管理
- 避免在Service层手动获取Connection后传入DAO——应由DAO从DataSource获取,由连接池统一管控
- 长事务(>5秒)会独占连接,应拆分为多个短事务,或改用消息队列异步化
监控与动态调优不可少
连接池不是“设完就不管”。需持续观察实际运行指标:
- 关注 activeCount(当前活跃连接数)是否长期接近 maxPoolSize —— 是扩容信号
- 观察 poolSize 与 idleCount 波动,若 idleCount 长期为0,说明连接紧张或SQL执行慢
- 结合MySQL的 SHOW PROCESSLIST 和 information_schema.PROCESSLIST,识别慢查询或未关闭连接
- 生产环境建议集成Prometheus + Grafana,监控连接池等待时间、创建失败次数等核心指标










