首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 8 小時連線逾時問題根因與解決:wait_timeout 參數調優

     編輯:MySQL 資料庫相關知識

現象

Java (Servlet/Tomcat) 應用閒置一晚,隔天首次請求失敗:

com.mysql.cj.jdbc.exceptions.CommunicationsException:
Communications link failure. Last packet sent 0 ms ago.

根因

MySQL 預設 wait_timeout = 28800 秒(8 小時)。閒置連線超過此時間被 Server 主動斷開,但連線池 (HikariCP/DBCP) 仍持有失效連線,借用時拋出異常。

驗證

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

解決方案對比

方案優點缺點推薦度
增大 wait_timeout簡單、徹底解決 Server 端斷線佔用連線資源久、需重啟生效⭐⭐⭐
連線池 validationQuery借用前檢測、自動重連每次借用額外查詢、舊版驅動無效⭐⭐
連線池 testOnBorrow + validationQuery標準做法需正確配置⭐⭐⭐⭐
autoReconnect=trueURL 參數簡單MySQL 5.1+ 已失效、不建議☆
定期心跳查詢應用層控制增加複雜度⭐⭐

最佳實踐:雙管齊下

1. Server 端:調大 wait_timeout (建議 24-48 小時)

# my.cnf / my.ini
[mysqld]
wait_timeout = 86400  # 24小時
interactive_timeout = 86400

重啟生效:systemctl restart mysqld

2. 連線池端:啟用驗證機制 (HikariCP 範例)

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://host:3306/db?useSSL=false");
config.setUsername("user");
config.setPassword("pass");
config.setConnectionTestQuery("SELECT 1");  // 輕量驗證
config.setMinimumIdle(5);
config.setMaximumPoolSize(20);
config.setIdleTimeout(300000);      // 5 分鐘閒置回收
config.setMaxLifetime(1800000);     // 30 分鐘強制換新
config.setConnectionTimeout(30000); // 取得連線超時
// 關鍵:閒置檢查間隔
config.setValidationTimeout(5000);

3. 監控指標

  • Threads_connected:當前連線數
  • Aborted_clients:異常斷開計數
  • 連線池指標:activeConnections、idleConnections、pendingThreads

參數上限

  • Windows:wait_timeout 最大 31536000 (365 天)
  • Linux:最大 2147483 (24 天)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved