4、数据库连接池调优:HikariCP、Druid 核心参数与 ERP 并发实战
数据库连接池,说白了就是 ERP 系统的「血管」。连接池没调好,业务逻辑写得再漂亮,到了高并发场景下照样崩。我见过太多项目,上线前压测一切正常,一上生产就报「连接超时」——十有八九是连接池参数没吃透。
今天咱们就掰开揉碎,聊聊 HikariCP 和 Druid 这两个主流连接池。我会结合 ERP 的真实场景,告诉你每个参数到底该怎么设。
4.1 连接池的核心参数:别被默认值坑了
先看三个最关键的参数。嗯,这也是面试高频题,但实际调优时很多人只会背公式。
| 参数名 | HikariCP | Druid | 作用 |
|---|---|---|---|
| 最大连接数 | maximumPoolSize | maxActive | 池子里最多能有多少个连接 |
| 最小空闲 | minimumIdle | minIdle | 池子里至少保持多少个空闲连接 |
| 超时时间 | connectionTimeout | maxWait | 等不到连接时,最多等多久 |
你可能会问:「最大连接数设大点不就行了?」
其实不是。连接数越大,数据库的上下文切换越严重。我调过一个 ERP 项目,把最大连接数从 200 降到 50,吞吐量反而提升了 30%。
4.2 最大连接数:不是越多越好
我个人习惯用这个公式做初始估算:
最大连接数 = (核心线程数 * (1 + 等待时间 / 处理时间))
举个例子:
ERP 的订单提交接口,平均处理时间 50ms,数据库等待时间 20ms。
应用服务器是 8 核,核心线程数设为 16。
那么:16 * (1 + 20/50) ≈ 22 个连接。
你看,算出来才 22。很多新手一上来就设 200,数据库扛不住,应用也扛不住。
ERP 场景建议:
- 普通业务接口(查询类):最大连接数 = 应用线程数 * 0.5
- 复杂报表/批处理:最大连接数 = 应用线程数 * 1.5
- 高并发秒杀/抢单:最大连接数 = 应用线程数 * 2(但要做好降级)
4.3 最小空闲连接:别让连接睡大觉
这个参数很多人忽略。设得太小,突发流量一来,连接池要现创建连接——创建连接可是很慢的,一次 TCP 握手加认证,少说几十毫秒。
设得太大呢?空闲连接占着数据库资源,MySQL 的 wait_timeout 一到期,连接就被踢了,反而浪费。
我建议这样设:
最小空闲 = 最大连接数 * 0.2 ~ 0.3
比如最大连接数 50,最小空闲就设 10~15。
但要注意:如果业务有明显的波峰波谷(比如 ERP 月底结账),可以适当调高最小空闲,让池子「预热」好。
避坑指南: 我曾经遇到一个案例,最小空闲设了 0,结果每天早上 8 点上班高峰期,系统响应慢得像蜗牛。后来改成 10,问题就解决了。说白了,就是连接池没来得及「热身」。
4.4 超时时间:别让用户等到天荒地老
超时时间有两个维度:
- 获取连接超时(connectionTimeout / maxWait):应用等连接池给连接,最多等多久
- 连接空闲超时(idleTimeout / minEvictableIdleTimeMillis):空闲连接多久没被用,就回收掉
对于 ERP 系统,我一般这样设:
| 场景 | 获取连接超时 | 空闲超时 |
|---|---|---|
| 在线交易(订单、支付) | 3 秒 | 10 分钟 |
| 后台报表 | 10 秒 | 30 分钟 |
| 批处理/定时任务 | 30 秒 | 60 分钟 |
为什么在线交易要设 3 秒?
你想想看,用户点「提交订单」,如果等 10 秒才报错,体验得多差。宁可快速失败,也别让用户干等。
4.5 HikariCP vs Druid:怎么选?
这两个我都用过。简单说下我的感受:
- HikariCP:轻量、快。Spring Boot 默认用它,不是没道理的。适合大部分 ERP 场景。
- Druid:功能全,有监控、有 SQL 拦截、有防 SQL 注入。适合需要精细化运维的团队。
我个人习惯:
小团队、快速迭代的项目,用 HikariCP,省心。
大企业、有 DBA 团队、需要监控 SQL 性能的,用 Druid。
注意: 不要同时用两个连接池!我见过一个项目,配置里配了 HikariCP,又引了 Druid 的依赖,结果两个池子互相抢连接,数据库连接数直接爆了。
4.6 实战调优步骤:照着做就行
好了,理论说完了,咱们来点实际的。假设你有一个 ERP 的订单模块,并发量大约 200 TPS,怎么调?
- 先压测:用 JMeter 模拟 200 并发,看数据库连接数曲线。
- 设初始值:最大连接数 50,最小空闲 10,获取超时 3 秒。
- 观察指标:看连接池的「活跃连接数」和「等待线程数」。
- 逐步调整:如果活跃连接经常接近最大值,就加 10 个;如果等待线程经常 > 0,就缩短超时时间。
- 加缓存兜底:热点数据(比如物料编码、客户信息)用 Redis 缓存,减少数据库压力。
// HikariCP 配置示例(Spring Boot)
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
// Druid 配置示例
spring.datasource.druid.max-active=50
spring.datasource.druid.min-idle=10
spring.datasource.druid.max-wait=3000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=600000
4.7 最后说两句
连接池调优,没有银弹。每个 ERP 的业务模型不一样,订单模块和库存模块的并发特征也完全不同。我的建议是:先压测,再调参,最后上生产观察一周。
我曾经因为偷懒,直接用了默认配置上线,结果月底结账时数据库连接池被打满,财务同事加班到凌晨两点……嗯,从那以后,我再也不敢轻视连接池调优了。
下一章咱们聊聊 SQL 层面的优化,那才是 ERP 性能的「深水区」。