資料庫連接池是 Java 企業級應用的命脈。Spring Boot 2.x 預設 HikariCP,但 Druid(阿里巴巴)在國內生態極強,DBCP2(Apache)仍有存量專案。本文針對三大主流連接池,從核心配置、監控指標、生產調優、避坑實錄四個維度,給出可直接落地的最佳實踐。
| 配置項 | HikariCP (預設) | Druid | DBCP2 |
|---|---|---|---|
| 依賴坐標 | com.zaxxer:HikariCP | com.alibaba:druid-spring-boot-starter | org.apache.commons:commons-dbcp2 |
| DataSource 類 | HikariDataSource | DruidDataSource | BasicDataSource |
| 核心參數前綴 | spring.datasource.hikari.* | spring.datasource.druid.* | spring.datasource.dbcp2.* |
| 最大連接數 | maximum-pool-size (預設 10) | max-active (預設 20) | max-total (預設 8) |
| 最小閒置 | minimum-idle (預設同最大) | min-idle | min-idle |
| 獲取超時 | connection-timeout (30s) | max-wait (60s) | max-wait-millis (30s) |
| 空閒驗證 | idle-timeout (10min) | min-evictable-idle-time-millis | min-evictable-idle-time-millis |
| 存活測試 | connection-test-query | validation-query + test-on-borrow | validation-query + test-on-borrow |
| 洩漏偵測 | leak-detection-threshold (0 關閉) | remove-abandoned-timeout + log-abandoned | remove-abandoned-timeout + log-abandoned |
spring:
datasource:
url: jdbc:mysql://db:3306/app?useSSL=false&serverTimezone=Asia/Shanghai
username: app_user
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 30 # 核心數 * 2 + 有效磁盤數,視壓測調整
minimum-idle: 10 # 保持熱連接,避免冷啟動延遲
connection-timeout: 20000 # 20s 業務容忍上限
idle-timeout: 300000 # 5min 回收閒置
max-lifetime: 1200000 # 20min 強制換新,防 MySQL 8hr 斷連
connection-test-query: SELECT 1 # MySQL 8.0+ 驅動可省略(內建 isValid)
pool-name: HikariCP-Primary
leak-detection-threshold: 60000 # 1min 未歸還報警
auto-commit: false # 交易邊界由 @Transactional 控制
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
spring:
datasource:
druid:
max-active: 30
min-idle: 10
max-wait: 20000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-on-borrow: false
test-on-return: false
test-while-idle: true # 關鍵:閒置期驗證,不阻塞業務
time-between-eviction-runs-millis: 60000
# 監控與防火牆
filters: stat,wall,log4j2
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.css,/druid/*"
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: ${DRUID_PASSWORD}
# 洩漏偵測
remove-abandoned: true
remove-abandoned-timeout: 180
log-abandoned: true
spring:
datasource:
dbcp2:
max-total: 30
max-idle: 10
min-idle: 5
max-wait-millis: 20000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1
test-on-borrow: true # 借用時驗證,簡單但有鎖爭用
test-while-idle: true
time-between-eviction-runs-millis: 60000
remove-abandoned-timeout: 180
log-abandoned: true
# DBCP2 無內建監控端點,需自行整合 Actuator/JMX
| 指標 | 含義 | 健康閾值 | 告警動作 |
|---|---|---|---|
HikariPool.PoolStats.activeConnections | 正在使用連接數 | < 80% max-pool-size | 擴容 / SQL 調優 / 限流 |
HikariPool.PoolStats.idleConnections | 閒置連接數 | > minimum-idle | 檢查洩漏 / 降低 min-idle |
HikariPool.PoolStats.threadsAwaitingConnection | 等待連接線程數 | = 0 | 立即擴容 / 排查長事務 |
DruidDataSource.getPoolingCount | 池中連接總數 | 接近 max-active | 同上 |
DruidDataSource.getExecuteCount | SQL 執行總次數 | 配合 QPS 基線 | 流量異常偵測 |
DBCP2.NumActive / NumIdle | JMX 暴露指標 | 同 Hikari | 同 Hikari |
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
export:
prometheus:
enabled: true
Grafana 匯入 HikariCP Dashboard (ID 10939) 或 Druid 官方模板,即時可視化。
try-with-resources 或 Spring JdbcTemplate/MyBatis 統一管理。PROPAGATION_NOT_SUPPORTED 掛起事務。Communications link failure。max-lifetime < wait_timeout - 30min(Hikari 建議 30min 安全邊際)。wall.variant=mysql、白名單 wall.allow-multi-statement=true、或關鍵路徑關閉 WallFilter。initialization-fail-timeout=-1(預設)啟動時強制連 DB 失敗則應用掛起。initialization-fail-timeout=60000 允許啟動期重試,健康檢查由 Kubernetes livenessProbe 把關。
新專案 / 高並發 / 低延遲敏感?
├─ 是 → HikariCP(預設、輕量、效能最強)
└─ 否 → 需要強 SQL 監控、防火牆、詳細日誌分析?
├─ 是 → Druid(國內生態最完善、阿里維護)
└─ 否 → 維護舊 DBCP2 專案 / 簡單內部工具?
├─ 是 → DBCP2(輕量、零依賴、但效能監控弱)
└─ 否 → 回到 HikariCP
leak-detection-threshold 守住底線。StatViewServlet+WallFilter 解決「慢 SQL 在哪、誰洩漏、有無注入」三大痛點。max-lifetime < DB wait_timeout、try-with-resources 全覆蓋、Actuator+Prometheus+Grafana 全鏈路可視化。把這份配置模板、監控大盤、避坑清單存入團隊 Wiki,下次上線前核對一遍,連接池不再是「黑盒」,而是可控、可觀、可信的基礎設施。