心跳包是什麼
01
什麼是activemq
activeMQ 是一種開源的,實現了 JMS1。1 規範的,面向訊息(MOM)的中介軟體,為應用程式提供高效的、
可擴充套件的、穩定的和安全的企業級訊息通訊
02
ActiveMq宕機怎麼辦
這得從
ActiveMQ 的儲存機制
說起。在通常的情況下,非持久化訊息是儲存在記憶體中的,持久化訊息是存
儲在檔案中的,它們的最大限制在配置檔案的
到一定程度,記憶體告急的時候,ActiveMQ 會將記憶體中的非持久化訊息寫入臨時檔案中,以騰出記憶體。雖 然都儲存到了檔案裡,但它和持久化訊息的區別是,重啟後持久化訊息會從檔案中恢復,非持久化的臨時 檔案會直接刪除。
那如果檔案增大到達了配置中的最大限制的時候會發生什麼?我做了以下實驗:
設定 2G 左右的持久化檔案限制,大量生產持久化訊息直到檔案達到最大限制,此時生產者阻塞,但消費
者可正常連線並消費訊息,等訊息消費掉一部分,檔案刪除又騰出空間之後,生產者又可繼續傳送訊息, 服務自動恢復正常。
設定 2G 左右的臨時檔案限制,大量生產非持久化訊息並寫入臨時檔案,在達到最大限制時,生產者阻塞,
消費者可正常連線但不能消費訊息,或者原本慢速消費的消費者,消費突然停止。整個系統可連線,但是 無法提供服務,就這樣掛了。
具體原因不詳,解決方案:
。
03
丟訊息怎麼辦?
這得從 java 的 java。net。SocketException 異常說起。簡單點說就是當網路傳送方傳送一堆資料,然後調 用 close 關閉連線之後。這些傳送的資料都在接收者的快取裡,接收者如果呼叫 read 方法仍舊能從快取中 。
讀取這些資料,儘管對方已經關閉了連線。但是當接收者嘗試傳送資料時,由於此時連線已關閉,所以會 發生異常。
這個很好理解。不過需要注意的是,當發生 SocketException 後,原本快取區中資料也作廢了。
此時接收者再次呼叫 read 方
法去讀取快取中的資料,就會報 Software caused connection abort: recv
failed 錯誤。
透過
抓包得知
,ActiveMQ 會每隔 10 秒傳送一個心跳包,這個心跳包是伺服器傳送給客戶端的,用來判 斷客戶端死沒死。如果你看過上面第一條,就會知道非持久化訊息堆積到一定程度會寫到檔案裡,
這個寫
的過程會阻塞所有動作,而且會持續 20 到 30 秒,並且隨著記憶體的增大而增大。當客戶端發完訊息呼叫
connection。close()時,會期待伺服器對於關閉連線的回答,如果超過 15 秒沒回答就直接呼叫 socket 層 的 close 關閉 tcp 連線了。這時客戶端發出的訊息其實還在伺服器的快取裡等待處理,不過由於伺服器心
跳包的設定,
導致發生了 java.net.SocketException 異常
,把快取裡的資料作廢了,沒處理的訊息全部丟 失。
解決方案:用持久化訊息,或者非持久化訊息及時處理不要堆積,或者啟動事務,啟動事務後,commit()
方法會負責任地等待伺服器的返回,也就不會關閉連線導致訊息丟失了