首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

解決 MySQL 8 小時閒置連線斷開:wait_timeout 原理與三種修正方案

     編輯:關於SqlServer

現象與錯誤訊息

Tomcat + MySQL 5.x 應用,隔夜閒置後首次請求失敗:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 0 ms ago

根因:MySQL 預設 wait_timeout = 28800 秒 (8 小時)

SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+

機制:連線閒置超過 `wait_timeout`,MySQL **主動切斷**連線。連線池 (DBCP/HikariCP/C3P0) 仍持有失效連線物件,借用時拋出上述異常。

三種修正方案(依推薦度排序)

方案一:調大 MySQL wait_timeout(治本,最簡單)

修改設定檔:

  • Windows: `my.ini`
  • Linux: `/etc/my.cnf` 或 `/etc/mysql/my.cnf`
[mysqld]
wait_timeout = 2592000  # 30 天 (單位:秒)
interactive_timeout = 2592000

重啟 MySQL 生效。最大值:Windows 365 天,Linux 24 天(舊版本),新版本均支援更大值。

✅ 優點:一次設定、所有連線池受益、無程式碼變更。
⚠️ 注意:過長會佔用連線資源,配合連線池 `maxIdle`、`minEvictableIdleTimeMillis` 合理規劃。

方案二:連線池驗證機制(治標,應用層自救)

主流連線池配置關鍵參數:

核心邏輯:**連線池定期/借用前主動驗證**,失效則丟棄重建,對應用透明。

方案三:JDBC URL 參數(舊版本有效,新版驅動已棄用)

jdbc:mysql://host:3306/db?autoReconnect=true&autoReconnectForPools=true

⚠️ MySQL Connector/J 5.1.39+ **不再支援** `autoReconnect`,官方明確建議使用連線池驗證機制。

最佳實踐組合拳

  1. MySQL `wait_timeout` 設為 **4-8 小時**(平衡資源釋放與閒置容忍)。
  2. 連線池 `idleTimeout` / `minEvictableIdleTimeMillis` 設為 **比 wait_timeout 短 30-60 分鐘**(如 3-7 小時)。
  3. 啟用 **借用前驗證** (`testOnBorrow` / `connectionTestQuery`)。
  4. 監控連線池指標:`ActiveConnections`、`IdleConnections`、`ThreadAwaitingConnection`、驗證失敗計數。

驗證方法

  1. 修改配置、重啟服務。
  2. 模擬閒置:停止應用流量,等待超過原 8 小時或設定的驩移時間。
  3. 發起請求,觀察是否無異常、日誌無 CommunicationsException。
  4. 檢查 MySQL `SHOW PROCESSLIST` 連線狀態正常。

結語

MySQL 8 小時斷連是**預設值陷阱**,非 Bug。**調大 wait_timeout + 連線池主動驗證**雙管齊下,是穩健、低成本、零業務侵入的標準解法。拒絕 `autoReconnect`,擁抱現代連線池最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
連線池關鍵配置
HikariCP (推薦)`idleTimeout` < `wait_timeout` (預設 10 分鐘)、`maximumPoolSize`、`connectionTestQuery: SELECT 1`、`validationTimeout`
DBCP2`testOnBorrow=true`、`validationQuery=SELECT 1`、`minEvictableIdleTimeMillis` < `wait_timeout`、`timeBetweenEvictionRunsMillis`
C3P0`testConnectionOnCheckout=true`、`preferredTestQuery=SELECT 1`、`idleConnectionTestPeriod` < `wait_timeout`