你有没有遇到过这种情况:系统白天跑得好好的,一到晚上批量任务上来,数据库连接直接爆掉,页面打不开,接口超时,运维半夜被叫起来重启服务?问题很可能就出在连接池参数没调好。
连接池是什么?
简单说,连接池就是提前建好一批数据库连接,放在那儿等着程序来用。不用每次操作都重新建立连接,省时间、减压力。但池子太大或太小,都会出问题。
核心参数有哪些?
以常见的 HikariCP 为例,这几个参数最关键:
- maximumPoolSize:池子里最多允许多少个连接
- minimumIdle:最少保持几个空闲连接
- connectionTimeout:获取连接最长等多久
- idleTimeout:空闲连接最多留多久
- maxLifetime:连接最长存活时间
maximumPoolSize 设多大合适?
很多人图省事直接设成100甚至200,结果数据库扛不住。MySQL 默认最大连接数是151,如果你每个应用都开100个连接,三个服务一上,数据库直接连满。
一个经验公式:
每核 CPU 支持 4-8 个活跃连接。假设你的服务部署在 4 核机器上,最大连接数建议控制在 20 以内。先设小点,再根据监控慢慢加。
别让连接“睡太久”
有些业务白天忙,夜里几乎没流量。minimumIdle 设成10,结果半夜10个连接全挂着,白白占资源。可以设成1或2,够用就行。
另外,maxLifetime 建议比数据库的 wait_timeout 小一点。比如 MySQL 的 wait_timeout 是 300 秒,那 maxLifetime 可以设成 250 秒,避免连接被数据库主动干掉导致异常。
实战配置示例
Spring Boot 项目中,application.yml 这么写:
spring:\n datasource:\n hikari:\n maximum-pool-size: 16\n minimum-idle: 4\n connection-timeout: 30000\n idle-timeout: 600000\n max-lifetime: 1800000\n pool-name: MyHikariPool
看日志比猜更有用
连接池配得好不好,不能靠拍脑袋。打开 HikariCP 的日志,关注有没有报 connection timeout 或者 connection leak。
比如出现 “Timeout during connection acquisition” 就说明 maximumPoolSize 不够用了,要么加大小,要么查查是不是有连接没及时释放。
不同环境要区别对待
开发环境可能就一个人测,maximumPoolSize 设成5就够了。测试环境并发高点,可以设到10-12。生产环境再根据压测结果调整,别照搬测试的配置。
还有,微服务多了更要精打细算。十个服务每个占20个连接,数据库就得支持200个并发,压力不小。这时候更得把每个池子控住。