應用啟動後運行正常,隔夜/閒置數小時後首次請求報 Communications link failure: The last packet sent successfully to the server was 43200 milliseconds ago, which is longer than the server configured value of 'wait_timeout'。本文深度剖析 wait_timeout 機制、連接池驗證策略,給出 C3P0/Hibernate 生產級配置模板。
wait_timeout=28800s (8h):閒置連接超過 8h 由 Server 主動斷開43200 milliseconds ago(43.2秒)誤導:實際是連接池驗證查詢間隔配置不當,導致僵屍連接存活過長C3P0 核心配置:
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property> <property name="hibernate.c3p0.preferredTestQuery">SELECT 1</property>
testConnectionOnCheckout=true:每次從池借用連接前執行 SELECT 1,失敗則丟棄重建<property name="hibernate.c3p0.idleConnectionTestPeriod">1800</property> -- 30分鐘 <property name="hibernate.c3p0.maxIdleTime">1800</property> -- 30分鐘超過則丟棄 <property name="hibernate.c3p0.maxIdleTimeExcessConnections">300</property>
idleConnectionTestPeriod:後台線程定期掃描空閒連接,執行 preferredTestQuerymaxIdleTime:空閒超時強制回收,避免連接長期佔用獨立線程每 30 分鐘執行 SELECT 1,但無法覆蓋連接池內所有連接,僅作補充。
<session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.useUnicode">true</property> <property name="hibernate.connection.characterEncoding">UTF-8</property> <!-- C3P0 連接池 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.timeout">1800</property> -- maxIdleTime <property name="hibernate.c3p0.max_statements">50</property> <property name="hibernate.c3p0.idleConnectionTestPeriod">1800</property> <property name="hibernate.c3p0.preferredTestQuery">SELECT 1</property> <property name="hibernate.c3p0.testConnectionOnCheckout">true</property> -- 核心 <property name="hibernate.c3p0.acquireRetryAttempts">30</property> <property name="hibernate.c3p0.acquireRetryDelay">1000</property> </session-factory>
<dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>mchange-commons-java</artifactId> <version>0.2.19</version> </dependency>
| 參數 | 含義 | 建議值 |
|---|---|---|
minPoolSize | 最小連接數 | 5-10 |
maxPoolSize | 最大連接數 | 20-50 (視業務) |
initialPoolSize | 初始化連接數 | min/max 之間 |
maxIdleTime | 空閒回收秒數 | 1800 (30min) |
idleConnectionTestPeriod | 空閒檢測間隔 | 1800 (30min) |
testConnectionOnCheckout | 借用時驗證 | true |
preferredTestQuery | 驗證 SQL | SELECT 1 |
acquireRetryAttempts | 獲取失敗重試次數 | 30 |
acquireRetryDelay | 重試間隔 ms | 1000 |
maxStatements | 全局 Statement 緩存 | 50-100 |
maxStatementsPerConnection | 單連接 Statement 緩存 | 100 |
idleConnectionTestPeriod**:若檢測剛結束、MySQL 隨後斷開,仍有窗口期testConnectionOnCheckout 是最後一道防線**,性能損耗可接受wait_timeout(如 7200),但**不能替代連接池驗證**NumBusyConnections、NumIdleConnections、NumFailedCheckouts