ActiveMQ版本:5.5.1
MQ 所使用的 MySQL 是 InnoDB存儲引擎
記錄人:@鄭昀
現象:
業務表面現象:無。系統現象:無。
日志信息:業務系統發送 MQ 消息時,下面這種錯誤日志斷斷續續地一直都有:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 60,001 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago.
|
原因:
ActiveMQ 持久化方案我們選的是 MySQL 。
MySQL 的全局變量 wait_timeout 默認是28800,單位是秒,即8小時。
運維部早先在測試 ActiveMQ 5.5 主從方案時,發現當 Master 宕機后,鎖(數據庫里的一個排他鎖)有可能沒有釋放,導致 Slave 無法成為 Master(
這是 ActiveMQ 5.5 的 BUG,已在 5.6.0和5.7.0 修復)。
所以運維部將 wait_timeout 參數調短為了
60秒,希望能加速鎖釋放。
當業務不繁忙時,也許會有60秒既不生產也不消費,因此 MySQL 主動斷開了 Connection 。此時,如果作為 MySQL Client 身份的 Broker Service,它的數據庫連接池對
連接斷開檢測和自動重連
做得不好的話,那么 Broker 首次訪問 DB 時 jdbc 就會報錯。
短期解決辦法:
將 ActiveMQ 所使用的 MySQL 的全局變量 wait_timeout 恢復為默認值 28800 。(已完成)
中期解決方法:
將 ActiveMQ 升級到 5.6.0或5.7.0 穩定版本。
相關的BUG:
ActiveMQ 的缺陷單
AMQ-1958 報告:
JDBC master/slave deadlock when connection is lost
影響版本:
4.1.2, 5.0.0, 5.1.0, 5.2.0
Fix版本:
5.6.0
狀態:2012年4月17日已修復
描述:
在一個純 JDBC Failover 場景下(
1 Master+1 Slave):如果 Master 失去了數據庫網絡連接,數據庫里的鎖將不會釋放。這樣 Slave 不知道 Master 已不能執行任務,Slave 仍嘗試不斷獲取鎖;當 Master 重啟后,它自己也無法獲得鎖,於是變身為 Slave;結果就是
0 Master+2 Slave 。
環境:Oracle 10,MySQL 5
(這也就是運維部在 ActiveMQ 5.5.1 測試場景所遇到的)
AMQ-3654 也報告類似問題:
JDBC Master/Slave : Slave cannot acquire lock when the master loose database connection
影響版本:
5.5.0
Fix版本:
5.7.0
狀態:2012年6月13日已修復
描述:與 AMQ-3654 描述一樣。只不過報告的版本號不一樣。
參考資源:
1)火丁老王,
MySQL里的wait_timeout
『wait_timeout 過大有弊端,其體現就是 MySQL 里大量的 SLEEP 進程無法及時釋放,拖累系統性能,不過也不能把這個指設置的過小,否則你可能會遭遇到“MySQL has gone away”之類的問題。』『在MySQL命令行里通過 SET來設置即可,避免服務重啟:mysql> set global wait_timeout=60;』『查有無生效,用 show global variables 查全局變量:mysql> show global variables like 'wait_timeout';單純使用 show variables 的話就等同於使用的是 show session variables,查詢的是會話變量,你會誤以為設置沒有生效。』
2)iteye,
關於 MySQL 的 wait_timeout 連接超時報錯解決方案
3)
AMQ-1958
4)以前有人提議在數據庫連接字符串中增加autoReconnect=true&failOverReadOnly=false,但這只對 MySQL 4.0 以前的版本有效,對 MySQL 5.0 以后無效。
『Master failure
If the master looses connection to the database or looses the exclusive lock then it immediately shuts down. If a master shuts down or fails, one of the other slaves will grab the lock and so the topology switches to the following diagram![]()
』
6)wait_timeout 參數說明
『 參數含義:服務器關閉非交互連接之前等待活動的秒數。在線程啟動時,根據全局wait_timeout值或全局interactive_timeout值初始化會話wait_timeout值,取決於客戶端類型(由mysql_real_connect()的連接選項CLIENT_INTERACTIVE定義)。
參數默認值:28800秒(8小時)』