傳統 JDBC 每次請求「獲取連接→打開→操作→關閉」,建立 TCP/握手/認證開銷巨大(數十毫秒),高併發下頻繁創建銷毀導致:數據庫連接數爆衝、應用線程阻塞、GC 壓力激增。連接池核心價值:連接復用、生命週期管理、監控統計。
| 維度 | DBCP 2.x | C3P0 0.9.5+ |
|---|---|---|
| 所屬基金會 | Apache Commons | 獨立項目 (mchange) |
| 核心依賴 | commons-pool2 | mchange-commons-java |
| Tomcat 默認 | 是 | 否 |
| 空閒連接回收 | 需配合 validationQuery + testWhileIdle | 原生支持 maxIdleTime/idleConnectionTestPeriod |
| PreparedStatement 緩存 | maxOpenPreparedStatements | 更強 maxStatements/maxStatementsPerConnection |
| 配置格式 | Properties / XML | XML (c3p0-config.xml) |
| Java 版本支持 | Java 7+ (DBCP2) | Java 8+ |
| 維護活躍度 | 較高 | 低(近年極少發布) |
# 數據庫連接 driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/day16?useSSL=false&serverTimezone=UTC username=root password=123456 # 池基本參數 initialSize=10 maxTotal=50 maxIdle=20 minIdle=5 maxWaitMillis=60000 # 連接驗證(關鍵:防止「斷連」) validationQuery=SELECT 1 testOnBorrow=false testOnReturn=false testWhileIdle=true timeBetweenEvictionRunsMillis=30000 minEvictableIdleTimeMillis=300000 numTestsPerEvictionRun=3 # 連接屬性 connectionProperties=useUnicode=true;characterEncoding=utf8;autoReconnect=true defaultAutoCommit=true defaultReadOnly=false defaultTransactionIsolation=READ_COMMITTED
public class DBCPUtils {
private static DataSource dataSource;
static {
try (InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties")) {
Properties props = new Properties();
props.load(in);
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close(ResultSet rs, Statement st, Connection conn) {
// 標準關閉邏輯:關閉順序 rs → st → conn(實際歸還池)
}
}
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc?useSSL=false</property>
<property name="user">root</property>
C3P0Utils 工具類
public class C3P0Utils {
private static ComboPooledDataSource cpds = new ComboPooledDataSource(); // 讀取 default-config
public static Connection getConnection() throws SQLException {
return cpds.getConnection();
}
// close 方法同 DBCPUtils
}
生產環境選型建議
- 首選 HikariCP:當前性能王者(基準測試碾壓 DBCP/C3P0)、代碼極簡、零依賴、Spring Boot 2.x 默認。
implementation 'com.zaxxer:HikariCP:5.0.1'
- 舊項目維護:
- Tomcat 容器管理 → 繼續用 DBCP2(兼容性最好)。
- 需強 Statement 緩存/空閒回收 → C3P0 仍可用,但建議遷移 HikariCP(
maximumPoolSize/maxLifetime/idleTimeout 原生支持)。
- 核心參數通用原則:
maxPoolSize ≈ (CPU核心數 × 2) + 有效磁盤數(經驗公式),典型 20-50。
connectionTimeout=30s、idleTimeout=10min、maxLifetime=30min(<30min 避開數據庫 wait_timeout)。
- 必須配置
validationQuery/preferredTestQuery + 空閒檢測,防止「晨間首請求失敗」。
- 監控指標:活躍連接數、空閒連接數、等待線程數、獲取連接耗時、SQL 執行耗時(集成 Micrometer/Prometheus)。
避坑清單
- [ ] 數據庫
max_connections > 應用總 maxPoolSize + 保留量。
- [ ] 連接池
maxLifetime < 數據庫 wait_timeout (MySQL 默認 8h)。
- [ ] 關閉連接時 只歸還池,不斷開物理連接,工具類
close() 僅調用 Connection.close()。
- [ ] 壓測驗證連接池穩定性:並發 200 線程持續 30 分鐘,無泄漏、無超時、無拒絕。
連接池是 Java 應用與數據庫間的「減震器」,選對池、配好參數、持續監控,是系統穩定性的基石。