核心解法是用连接池替代直连,再配合合理配置与使用规范;不加池子的每次getConnection()都会触发TCP握手、身份认证等高开销操作,高并发下易压垮数据库或应用,必须启用HikariCP或Druid等高性能连接池。

核心解法是用连接池替代直连,再配合合理配置与使用规范。不加池子的每次 getConnection() 都会触发 TCP 握手、身份认证、权限校验,高并发下瞬间压垮数据库或应用本身。
必须启用高性能连接池
别用 DriverManager 手动建连。推荐 HikariCP(轻量、快、默认配置即合理)或 Druid(监控强、功能全)。以 HikariCP 为例:
- 在 pom.xml 中引入依赖:
com.zaxxer:hikari-cp:5.0.1 - 初始化时设置关键参数:最大连接数(如 20)、连接超时(≤30s)、空闲连接存活时间(如 10 分钟)
- 确保 DataSource 是单例全局复用,不是每次 DAO 调用都 new 一个
连接池参数需贴合业务压力
盲目设大值反而有害。例如 CPU 核数为 8 的服务,最大连接数设 200 可能导致数据库连接耗尽、线程排队、响应延迟飙升。
- 初始连接数(initialSize):设为最小空闲数(minIdle),避免冷启动时连接创建阻塞
- 最大活跃数(maximumPoolSize):参考公式 ≈(QPS × 平均查询耗时)× 1.2,再结合数据库最大连接上限反推
- 连接超时(connectionTimeout):建议 30 秒内,超时后应快速失败而非无限等待
- 空闲连接回收(idleTimeout):设为 600000(10 分钟),防连接长期空闲被 DB 主动断开
代码层规避隐式连接争用
即使有池子,写法不对照样卡住连接。常见错误包括:
- 在事务外提前 close() 连接,但实际业务还在用 PreparedStatement —— 导致连接被归还,语句执行报错
- try-with-resources 写法中未显式控制事务边界,造成连接未及时释放
- 批量操作仍用单条 executeUpdate(),未启用 addBatch() + executeBatch()
- 长事务持有连接过久(如含 HTTP 调用、文件读写),应拆分为短事务 + 异步后续处理
配合数据库端协同优化
连接池只是客户端手段,服务端也要配合:
- MySQL 设置
wait_timeout和interactive_timeout≥ 连接池的 idleTimeout,避免连接被 DB 主动 kill - 检查
max_connections是否足够(如默认 151 显然不够高并发) - 开启慢查询日志,定位长期占用连接的 SQL(如没走索引的 COUNT(*) 或 GROUP BY)
- 对热点表考虑读写分离,把只读流量导到从库,减轻主库连接压力
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











