连接池配置
数据库连接的创建开销高(TCP 握手 + 认证),连接池通过预创建并复用连接大幅降低延迟。Spring Boot 默认集成 HikariCP,国内项目也广泛使用阿里的 Druid。
HikariCP(默认)
引入任何 spring-boot-starter-data-* 依赖时,HikariCP 自动成为连接池实现。
基础配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
# 连接池大小
minimum-idle: 5 # 空闲时维持的最小连接数
maximum-pool-size: 20 # 最大连接数(核心参数)
# 超时配置
connection-timeout: 30000 # 获取连接的最长等待时间(ms),超时抛异常
idle-timeout: 600000 # 空闲连接被回收的时间(ms)
max-lifetime: 1800000 # 连接最大存活时间(ms),需 < 数据库 wait_timeout
# 连接检测
connection-test-query: SELECT 1 # MySQL 可省略,HikariCP 有更高效的内部检测
keepalive-time: 120000 # 定期保活(防止防火墙断开空闲连接)
pool-name: HikariPool-Main连接池大小公式
经验公式(OLTP 场景):
最佳连接数 ≈ 核心线程数 × 2 + 有效磁盘数
HikariCP 官方建议:连接数越少越好,过多连接会加剧数据库竞争。实际调优以监控数据为准,而非拍脑袋。
| 场景 | 推荐 maximum-pool-size |
|---|---|
| 单实例 8 核,纯 OLTP | 20~40 |
| 8 核,含大量慢查询 | 10~20 |
| 多实例部署(每实例) | 总连接数 / 实例数 |
max-lifetime 说明
数据库服务端通常有连接超时(MySQL 默认 wait_timeout=28800s,即 8 小时)。max-lifetime 必须小于数据库的超时时间,否则 HikariCP 持有的连接已被服务端关闭,使用时会报 Connection is closed:
hikari:
max-lifetime: 1800000 # 30 分钟,远小于 MySQL 8 小时超时Druid
Druid 是阿里开源的连接池,内置 SQL 监控、慢查询日志、数据库密码加密等功能。
引入依赖
implementation 'com.alibaba:druid-spring-boot-3-starter:1.2.22'配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 连接池大小
initial-size: 5
min-idle: 5
max-active: 20
# 超时
max-wait: 60000 # 获取连接最大等待时间(ms)
min-evictable-idle-time-millis: 300000
max-evictable-idle-time-millis: 900000
# 连接检测
test-while-idle: true # 从池中取连接时检测
test-on-borrow: false # 借出时检测(影响性能,一般关闭)
test-on-return: false
validation-query: SELECT 1
keep-alive: true
# SQL 监控(Druid 特色)
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 1000 # 超过 1s 记录为慢 SQL
merge-sql: true
wall:
enabled: true # SQL 防火墙,防注入
# 监控控制台
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin123
allow: 127.0.0.1 # 只允许本地访问
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.css,/druid/*"访问 http://localhost:8080/druid 查看监控面板(SQL 统计、慢查询、连接池状态)。
生产环境建议关闭或限制
stat-view-servlet,防止内部监控数据暴露。
数据库密码加密
# 生成加密密钥和密文
java -cp druid-1.2.x.jar com.alibaba.druid.filter.config.ConfigTools yourPassword
# 输出:privateKey / publicKey / password(密文)spring:
datasource:
druid:
password: <加密后的密文>
filter:
config:
enabled: true
connection-properties: config.decrypt=true;config.decrypt.key=<publicKey>多数据源连接池
多数据源场景下每个 DataSource 独立配置连接池:
@Configuration
public class DataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.primary.hikari")
public DataSource primaryDataSource(
@Value("${spring.datasource.primary.url}") String url,
@Value("${spring.datasource.primary.username}") String username,
@Value("${spring.datasource.primary.password}") String password
) {
return DataSourceBuilder.create()
.url(url).username(username).password(password)
.build();
}
@Bean
@ConfigurationProperties("spring.datasource.secondary.hikari")
public DataSource secondaryDataSource(...) { ... }
}spring:
datasource:
primary:
url: jdbc:mysql://primary-host:3306/main
hikari:
maximum-pool-size: 20
pool-name: HikariPool-Primary
secondary:
url: jdbc:mysql://secondary-host:3306/analytics
hikari:
maximum-pool-size: 10
pool-name: HikariPool-Secondary多数据源详见 多数据源。
连接池监控(Actuator)
management:
endpoints:
web:
exposure:
include: health, metrics
endpoint:
health:
show-details: alwaysHikariCP 自动暴露指标,可通过 Actuator 查看:
GET /actuator/metrics/hikaricp.connections.active # 活跃连接数
GET /actuator/metrics/hikaricp.connections.idle # 空闲连接数
GET /actuator/metrics/hikaricp.connections.pending # 等待获取连接的线程数
GET /actuator/metrics/hikaricp.connections.acquire # 获取连接的平均耗时
应用监控详见 Actuator监控。
HikariCP vs Druid 对比
| 对比项 | HikariCP | Druid |
|---|---|---|
| 性能 | 极高(业界最快) | 略低,但差距不大 |
| 监控 | 依赖 Micrometer / Actuator | 内置 Web 控制台,开箱即看 |
| SQL 拦截 | 无 | 内置统计、慢查询、防注入 |
| 密码加密 | 不内置 | 内置 ConfigFilter |
| 配置复杂度 | 低 | 中 |
| 适用场景 | 对性能敏感,有独立监控体系 | 需要 SQL 审计、内置监控的项目 |
选型建议:
- 新项目 + 有 Prometheus/Grafana:HikariCP(默认,省心)
- 需要 SQL 审计 / 慢查询分析 / 简单内置监控:Druid
常见问题
连接池耗尽(Connection timeout)
HikariPool - Connection is not available, request timed out after 30000ms
排查方向:
maximum-pool-size设置过小- 存在连接泄漏:事务未提交/回滚,连接未释放
- 慢查询导致连接长时间占用
定位连接泄漏:
hikari:
leak-detection-threshold: 5000 # 连接被借出超过 5 秒打警告日志8 小时断连(CommunicationsException)
MySQL wait_timeout 默认 8 小时,长时间无请求后连接被服务端关闭:
hikari:
max-lifetime: 1800000 # 30 分钟,强制主动替换连接
keepalive-time: 120000 # 每 2 分钟发一次 keepalive 包
connection-test-query: SELECT 1读写分离场景
连接池配合读写分离路由时,主库写连接和从库读连接应使用独立的连接池,详见 读写分离。
相关链接
- 数据访问 — JDBC / JPA 数据访问层概览
- 多数据源 — 多数据源的 DataSource 独立配置
- 读写分离 — 主从连接池路由策略
- Actuator监控 — 连接池指标暴露与告警
- 性能调优 — 连接池大小与线程池协同调优