你有没有遇到过这样的情况?公司后台系统平时用着好好的,一到月底报表高峰期,页面就卡得不行,用户抱怨连天。查来查去,数据库没撑住,但CPU和内存都没跑满,问题出在哪?很多时候,就是连接池没调好。
连接池到底在干啥
我们可以把数据库连接想象成银行柜台的服务窗口。每次用户操作都要“排队开窗”,开一个新连接成本不低。连接池就是提前开好一批窗口,谁要用就从池子里拿,用完还回来,避免反复开关带来的开销。
但池子不是越大越好。开100个窗口,结果只有10个人办事,资源白白浪费;只开5个,赶上促销活动几百人同时来,大家全堵在门口,系统直接变慢。
常见性能陷阱
很多项目上线时直接用框架默认配置,比如HikariCP默认最大连接数是10。对于小应用没问题,但业务一增长,就成了瓶颈。另一种极端是盲目设成100甚至200,导致数据库连接数爆满,线程争抢资源,反而拖垮数据库。
还有一个容易被忽视的问题:连接泄漏。代码里用了连接但忘了归还,池子里的连接越来越少,到最后谁都拿不到,系统就卡死了。这就像借书不还,图书馆的书慢慢都被占着,后面的人一本都借不到。
怎么调才合理
关键看两个指标:平均并发请求数和数据库处理单请求的耗时。简单估算公式是:最大连接数 ≈ 并发请求数 × 平均响应时间(秒) / 数据库处理耗时(秒)。
举个例子,你的服务每秒处理50个请求,每个请求中数据库操作平均耗时20ms,那理论最优连接数大约是 50 × 0.02 = 1。当然实际要留余量,设成5~10比较稳妥。
如果系统有突发流量,比如秒杀活动,可以配合使用“超时等待”和“最小空闲连接”。保持几个常驻连接,避免冷启动延迟。
实际配置参考
以Spring Boot常用的HikariCP为例:
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=2
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
这个配置适合日活几千的小型服务。如果是高并发场景,maximum-pool-size 可以根据压测结果逐步上调,同时监控数据库的活跃连接数和CPU使用率。
别忘了监控
光配好了还不算完。加上监控才能及时发现问题。HikariCP自带的健康检查端点可以看当前活跃连接、等待线程数等信息。如果发现经常有线程等待获取连接,说明池子小了;如果活跃连接长期很低,说明资源浪费。
某电商后台曾经因为连接池设得太小,大促时订单创建接口超时率飙升。后来把最大连接从8调到20,配合数据库索引优化,接口成功率立刻回到99.9%以上。
连接池不是设一次就一劳永逸的。业务量变了,SQL效率变了,都需要重新评估。定期看看监控图表,比任何理论公式都管用。