首頁 > 曲藝

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

作者:由 怡子科技 發表于 曲藝日期:2022-12-18

心跳包是什麼

01

什麼是activemq

activeMQ 是一種開源的,實現了 JMS1。1 規範的,面向訊息(MOM)的中介軟體,為應用程式提供高效的、

可擴充套件的、穩定的和安全的企業級訊息通訊

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

02

ActiveMq宕機怎麼辦

這得從

ActiveMQ 的儲存機制

說起。在通常的情況下,非持久化訊息是儲存在記憶體中的,持久化訊息是存

儲在檔案中的,它們的最大限制在配置檔案的節點中配置。但是,在非持久化訊息堆積

到一定程度,記憶體告急的時候,ActiveMQ 會將記憶體中的非持久化訊息寫入臨時檔案中,以騰出記憶體。雖 然都儲存到了檔案裡,但它和持久化訊息的區別是,重啟後持久化訊息會從檔案中恢復,非持久化的臨時 檔案會直接刪除。

那如果檔案增大到達了配置中的最大限制的時候會發生什麼?我做了以下實驗:

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

設定 2G 左右的持久化檔案限制,大量生產持久化訊息直到檔案達到最大限制,此時生產者阻塞,但消費

者可正常連線並消費訊息,等訊息消費掉一部分,檔案刪除又騰出空間之後,生產者又可繼續傳送訊息, 服務自動恢復正常。

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

設定 2G 左右的臨時檔案限制,大量生產非持久化訊息並寫入臨時檔案,在達到最大限制時,生產者阻塞,

消費者可正常連線但不能消費訊息,或者原本慢速消費的消費者,消費突然停止。整個系統可連線,但是 無法提供服務,就這樣掛了。

具體原因不詳,解決方案:

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

03

丟訊息怎麼辦?

這得從 java 的 java。net。SocketException 異常說起。簡單點說就是當網路傳送方傳送一堆資料,然後調 用 close 關閉連線之後。這些傳送的資料都在接收者的快取裡,接收者如果呼叫 read 方法仍舊能從快取中 。

讀取這些資料,儘管對方已經關閉了連線。但是當接收者嘗試傳送資料時,由於此時連線已關閉,所以會 發生異常。

這個很好理解。不過需要注意的是,當發生 SocketException 後,原本快取區中資料也作廢了。

此時接收者再次呼叫 read 方

法去讀取快取中的資料,就會報 Software caused connection abort: recv

failed 錯誤。

透過

抓包得知

,ActiveMQ 會每隔 10 秒傳送一個心跳包,這個心跳包是伺服器傳送給客戶端的,用來判 斷客戶端死沒死。如果你看過上面第一條,就會知道非持久化訊息堆積到一定程度會寫到檔案裡,

Java什麼是activemq?怎麼解決宕機?丟訊息怎麼辦?

這個寫

的過程會阻塞所有動作,而且會持續 20 到 30 秒,並且隨著記憶體的增大而增大。當客戶端發完訊息呼叫

connection。close()時,會期待伺服器對於關閉連線的回答,如果超過 15 秒沒回答就直接呼叫 socket 層 的 close 關閉 tcp 連線了。這時客戶端發出的訊息其實還在伺服器的快取裡等待處理,不過由於伺服器心

跳包的設定,

導致發生了 java.net.SocketException 異常

,把快取裡的資料作廢了,沒處理的訊息全部丟 失。

解決方案:用持久化訊息,或者非持久化訊息及時處理不要堆積,或者啟動事務,啟動事務後,commit()

方法會負責任地等待伺服器的返回,也就不會關閉連線導致訊息丟失了