连接池参数治理-HikariCP怎么配才稳

连接池参数治理:HikariCP 在金仓数据库场景下怎么配才稳

应用能连上数据库,只是第一步。真正到了并发访问的情况下,连接池才是应用和数据库之间最关键的缓冲层。连接池配得太小,接口会排队;配得太大,数据库会被大量连接拖住;超时时间不合理,会造成请求堆积;连接泄漏没发现,会让系统越跑越慢。

Spring Boot 默认常用 HikariCP 作为连接池。本文围绕 Windows 11 本地开发、CentOS 7.6 服务器上的金仓数据库,讲清楚 HikariCP 的关键参数怎么理解、怎么配置、怎么验证。示例连接继续使用第一篇创建的 kb_appapp_user

@toc


一、为什么不能只用默认值

很多项目第一次接入数据库时,只写了:

yaml 复制代码
spring:
  datasource:
    url: jdbc:kingbase8://192.168.10.101:54321/kb_app
    username: app_user
    password: App_user_123

这样确实能启动,也能访问接口。但默认连接池参数不一定适合你的业务:

  • 并发高时,连接不够用,请求会等待。
  • 最大连接数过大,会挤占数据库会话资源。
  • 连接获取超时过长,会让用户请求长时间卡住。
  • 空闲连接保留过多,会浪费数据库连接。
  • 连接泄漏没有检测,问题会拖到生产事故才暴露。

连接池不是越大越好,它要和应用线程数、数据库最大连接数、业务 SQL 平均耗时一起设计。

二、先看数据库能承受多少连接

在调 HikariCP 之前,先进入金仓数据库查看最大连接数:

sql 复制代码
SHOW max_connections;

说明:下文用于观察会话的运行状态视图,请以你当前 KingbaseES 版本和产品手册为准;如果视图名或字段名不同,可以先在 ksql 中通过 \d、图形化工具元数据或管理员手册确认后再替换。

再看当前连接情况:

sql 复制代码
SELECT state, COUNT(*)
FROM sys_stat_activity
GROUP BY state
ORDER BY COUNT(*) DESC;

如果你的环境中视图名称或字段略有差异,以实际版本为准。核心思路是确认两件事:

  • 数据库最多允许多少连接。
  • 当前已经用了多少连接。

比如数据库最大连接数是 100,但同一台数据库还要服务后台任务、报表工具、运维工具和其他应用,那么单个应用就不能独占全部连接。一个比较稳妥的起点是先给单个应用 10 到 30 个连接,再根据压测结果调整。

三、HikariCP 核心参数

一个基础配置示例:

yaml 复制代码
spring:
  datasource:
    url: jdbc:kingbase8://192.168.10.101:54321/kb_app
    username: app_user
    password: App_user_123
    hikari:
      pool-name: kb-app-pool
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 3000
      idle-timeout: 600000
      max-lifetime: 1800000
      validation-timeout: 2000
      leak-detection-threshold: 10000

下面逐个解释。

1. maximum-pool-size

最大连接数,决定这个应用最多同时占用多少数据库连接。

不要拍脑袋设置成 100,应该综合看:

  • 数据库 max_connections
  • 同库其他应用数量。
  • 应用实例数量。
  • 接口并发量。
  • SQL 平均耗时。

举个例子,如果有 4 个应用实例,每个实例配置 maximum-pool-size=50,理论上最多会占用 200 个数据库连接。很多连接数耗尽问题就是这样被配置放大的。

2. minimum-idle

最小空闲连接数,表示连接池尽量保留多少空闲连接。

开发环境可以小一点,例如 2 到 5。生产环境要结合流量波动来定。如果业务有明显峰值,可以保留一定空闲连接减少临时建连成本,但不要让空闲连接长期过多。

3. connection-timeout

从连接池获取连接的最长等待时间。示例中配置为 3000 毫秒。

这个参数不建议太长。如果接口拿不到连接,说明系统已经拥塞了。让请求卡 30 秒再失败,只会拖垮应用线程。一般可以从 3 到 5 秒开始,再结合业务容忍度调整。

4. idle-timeout

空闲连接存活时间。超过这个时间的空闲连接可能被回收。

如果业务低峰期很长,可以适当缩短,减少空闲连接占用。不要频繁回收又频繁创建,否则会增加数据库建连压力。

5. max-lifetime

连接最大生命周期。超过后连接会被连接池替换。

这个值要小于网络设备、数据库或中间层可能主动断开连接的时间。常见起点是 30 分钟。不要设置成无限长。

6. leak-detection-threshold

连接泄漏检测阈值。某个连接被借出超过指定时间仍未归还,就会打印告警日志。

开发和测试环境建议打开,例如 10 秒或 30 秒。生产环境是否开启,需要结合日志量和性能影响综合评估。代码存在连接未关闭问题时,这个参数的告警日志可以直接定位到调用栈。

四、如何估算最大连接数

可以用一个简单思路估算:

text 复制代码
单实例最大连接数 = 目标并发请求数 * 单请求数据库占用时间 / 请求总耗时

举例:

  • 单实例目标并发请求数:100
  • 单个请求平均耗时:200ms
  • 其中数据库操作耗时:40ms

那么同时占用数据库连接的请求大约是:

text 复制代码
100 * 40 / 200 = 20

此时单实例连接池最大连接数可以先设置为 20 到 30,再通过压测观察。这个估算不是绝对公式,但比直接设置成 100 更可靠。

五、在数据库侧观察连接池效果

应用启起来之后。咱们得在数据库里面看看,这个连接到底是从哪来的。你可以执行下面这个SQL:

sql 复制代码
SELECT usename, application_name, client_addr, state, COUNT(*)
FROM sys_stat_activity
GROUP BY usename, application_name, client_addr, state
ORDER BY COUNT(*) DESC;

其实我建议你啊。在 JDBC URL 那里,用 ApplicationName 这个参数给应用设个标识。这样从数据库那边看连接来源,就方便多了:

text 复制代码
jdbc:kingbase8://192.168.10.101:54321/kb_app?ApplicationName=kb-app-demo

你设好之后呢。sys_stat_activity.application_name 这个字段,就会把对应的应用名称显示出来。通常来说,如果有多个应用,或者多个实例共用同一个数据库。这个方法就特别管用。

那么你需要重点看这几个东西:

  • app_user 当前有多少个连接。
  • 空闲连接是不是长期太多了。
  • 活跃连接是不是一直快到连接池上限了。
  • 有没有那种长时间都不释放的连接。

要是应用刚启动就建了一大堆连接。那你去查查 minimum-idle 这个参数。要是压测的时候,大量请求报获取连接超时。那你就得查查 SQL 耗时、连接池上限,还有应用的线程数了。

六、连接池和应用线程池要一起看

很多项目调数据库连接池的时候。往往仅仅只是看了连接池自己。却把 Web 容器的线程池给忽略了。这是一个问题。

那为什么会这样呢?你想啊。如果 Tomcat 最大线程数是 100。然后 Hikari 最大连接数只有 10。那么在大量接口都要访问数据库的情况下。那 90 个线程可能就得排队等连接了。

反过来也是。Tomcat 最大线程数是 100。Hikari 最大连接数也是 100。要是数据库扛不住这么多连接的话。数据库那边就会变成瓶颈了。

那么更稳妥的思路是啥呢?

  • 先把 Web 线程池控制住。别无限地接请求。
  • 接着再把数据库连接池控制住。别让数据库被打满了。
  • 最后就是通过压测。去看看平均响应时间、P95、连接池等待时间,还有数据库的活跃会话。

七、开发环境推荐配置

Windows 11 本地开发环境的话。配置可以保守一点:

yaml 复制代码
spring:
  datasource:
    hikari:
      pool-name: kb-dev-pool
      maximum-pool-size: 5
      minimum-idle: 1
      connection-timeout: 3000
      idle-timeout: 300000
      max-lifetime: 1800000
      leak-detection-threshold: 10000

其实开发环境嘛。重点真不是吞吐量。重点在于尽早发现连接泄漏、账号权限不对,还有 SQL 错误这些情况。

八、测试和生产环境建议

测试环境的话,你可以参考这个:

yaml 复制代码
spring:
  datasource:
    hikari:
      pool-name: kb-test-pool
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 3000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 30000

生产环境那就得结合压测结果来看了。我是不建议你直接照抄的。至少你得确认下面这几点:

  • 数据库最大连接数是多少。
  • 应用实例有几个。
  • 是不是还有报表、任务、或者管理工具在共用这个数据库。
  • 高峰期的时候,SQL 平均耗时是多少,慢 SQL 有多少。
  • 连接获取超时的次数多不多。

九、常见配置误区

1. 最大连接数越大越好

连接数太大的话。数据库调度的压力就会变大。很多时候啊。你把慢 SQL 减少一点。往往比增加连接数有效得多。

2. 连接获取超时设置很长

这会让用户的请求一直挂住。也会把应用线程给占住。系统拥塞的时候。其实应该让它快点失败,然后触发告警。

3. 开发环境不开泄漏检测

连接泄漏这东西。越早发现成本越低。开发环境的情况的话,还是应该把泄漏检测打开。

4. 多个应用实例没有合并计算连接数

每个实例 30 个连接。10 个实例就是 300 个连接了。扩容应用的时候。你必须重新核算一下数据库的连接预算。

十、小结

HikariCP 的参数。它不是孤立的配置。你得和数据库最大连接数、应用实例数、Web 线程池,还有 SQL 平均耗时一起综合考虑。稳妥的做法就是保守起步。然后压测验证。接着观察数据库会话。最后再逐步去调整。

下一篇我们继续往生产问题靠近。当连接数突然暴涨、接口开始卡住的时候。怎么从数据库会话、应用线程池和连接池日志这三条线一起去排查。

相关推荐
wWYy.1 小时前
Mysql:二级索引
数据库·mysql
jnrjian1 小时前
PG 导出表为excel iconv 乱码
数据库·postgresql
DLYSB_1 小时前
数据库连接池爆满导致全线宕机:我用 Go 写了个“现场声光报警器”,比钉钉快了 10 倍
数据库·golang·钉钉·报警灯
ClickHouseDB1 小时前
Postgres正则表达式性能优化:pg_re2扩展的引入与应用
数据库
艾莉丝努力练剑1 小时前
【MYSQL】MYSQL学习的一大重点:视图
android·服务器·数据库·学习·mysql·面试·视图
三江番长 陀舍古帝2 小时前
细说SQL Server中的加密
运维·服务器·数据库
艾莉丝努力练剑2 小时前
【MYSQL】MYSQL学习的一大重点:事务(下)- InnoDB 事务隔离性原理(MVCC 视角)
android·数据库·b树·sql·学习·mysql·面试
小园子的小菜3 小时前
Redis 核心原理深度解析:从数据结构、IO 模型到持久化机制
数据库·redis·缓存
YUS云生3 小时前
大模型学习·第44天:Chroma向量数据库与RAG链式组装
数据库·学习