activemq消息持久化_ActiveMQ 5.x中的消息持久性
activemq消息持久化
我被問了很多關于ActiveMQ如何存儲消息(或在某些情況下不存儲)的基本知識。 這是它的高級解釋。 注意,上下文在JMS中。 如果您使用ActiveMQ的非JMS客戶端(即STOMP,AMQP,MQTT等),則在某些情況下行為可能有所不同。
ActiveMQ
在不丟失標記為“持久”的消息方面,JMS持久性保證非常強大。 讓我們看看它如何適用于ActiveMQ
主題
主題是一種廣播機制。 它們使我們能夠在JMS領域中實現發布-訂閱語義。 但是,如果我們將消息標記為“持久”并且沒有訂閱者,會發生什么情況? 在任何普通廣播中(例如,我去市區并開始大喊ActiveMQ的出色表現),如果沒有訂閱者(3a,周圍沒有人聽到我的聲音……)如果我不在,一定是一個美好的夜晚在3a)會發生什么? 沒有。 沒有人聽到。 然后我們繼續前進。 如果您發布消息(持久的或非持久的)并且沒有訂閱者(沒有活動的訂閱者和持久的訂閱者),ActiveMQ對該消息不做任何事情。
ActiveMQ僅在有持久訂戶(活動或不活動)的情況下存儲消息。 對于非活動的持久訂閱,ActiveMQ會將標記為“持久”的消息存儲到非易失性存儲中,并等待訂閱者重新加入訂閱。 屆時它將嘗試傳遞消息。
Queue列
對于隊列,ActiveMQ使用簡單的默認協議來處理“持久”消息。 我們基本上阻塞了主要生產者線程,并等待確認經紀人實際上已收到消息:
制片人:
- 生產者發送消息
- 生產者阻止,等待來自代理的ACK
- 如果成功的確認,生產者繼續
經紀人:
- 收到消息
- 將消息存儲到磁盤
- 發回ACK
對于“非持久”發送,流程是不同的。 我們以“即發即棄”模式發送郵件。 主生產者線程不會被阻塞,并且在ActiveMQ連接傳輸線程上異步發生任何ACK或其他響應:
- 生產者發送消息
- 生產者繼續其線程,不會阻塞
- 生產者最終在與主生產者線程不同的單獨線程上獲得ACK
- 如果失敗,則客戶端可以訂閱JMS ExceptionListener以獲得通知
交易發送?
我們可以通過分批一次發送多個消息來提高發送給代理的性能。 這樣可以更有效地利用網絡以及代理存儲。 發送交易時,您必須意識到一個重要的區別。 TX會話的打開和關閉(回滾/提交)都是與代理的同步交互, 但是 ,TX窗口中每個消息的發送都是異步發送的。 如果一切順利,這是可以的,因為代理將這些消息分批處理。 但是,如果出現運輸錯誤怎么辦? 還是代理用完了空間來保存這些消息?
我們需要設置一個ExceptionListener來監視這些發送期間的錯誤。 我們還需要(或應該)設置一個客戶端發送“生產者窗口”,以允許我們在代理耗盡資源時強制執行生產者流控制。 有關更多信息,請參見ActiveMQ生產者流控制 。
更改默認值
生產者上有趣的設置,可以更改以下行為:
- useAsyncSend –始終異步等待ACK,即使在持久發送和提交中也是如此
- alwaysSyncSend –強制所有發送(包括非持久性或事務性發送)始終等待來自代理的ACK
人們通常想要使用默認值。
存儲
對于ActiveMQ的生產用途,我目前建議使用共享存儲方法 。 在這種情況下,我們需要知道存儲層發生了什么,以了解ActiveMQ的保證。
默認情況下,ActiveMQ將實現JMS持久性要求,該要求基本上規定了所存儲的消息必須在崩潰后幸免。 為此,默認情況下,我們將在文件系統上執行“ fsync”。 現在,每個系統上發生的情況將取決于您使用的操作系統,網絡,存儲控制器,存儲設備等。 對于需要持久存儲消息并且不是特定于ActiveMQ的任何類型的數據庫,這都是您期望的。
當我們寫入ActiveMQ事務日志時,我們需要讓OperatingSystem通過調用fsync將日志刷新到磁盤。 基本上發生的是,我們迫使操作系統回寫用于將文件更改緩存到存儲介質的頁面文件緩存。 它還鼓勵存儲介質執行將數據“存儲”到磁盤所需的操作(取決于實現):
一些存儲控制器具有自己的緩存,需要刷新。 磁盤驅動器具有自己的緩存,等等。其中一些緩存由電池支持,并且可能以自己的時間間隔寫回,等等。為了使您了解通過ActiveMQ運行的消息的持久性,您應該了解您的存儲層。
消費者
最后,難題的最后一部分是我們如何向消費者傳遞/分發消息以及他們如何確認。 ActiveMQ JMS庫為您處理了所有這些,因此您不必擔心是否會丟失消息。
消息將被分發給消費者,直到達到駐留在消費者身上的某個“預取”緩沖區為止。 這可以通過使使用者上的可用消息緩存準備好進行處理,然后在使用者使用它們時重新填充此緩存來幫助加速消息處理。 在ActiveMQ中,這些預取的消息在控制臺中表示為“運行中”。 這一點取決于消費者來處理這些消息并對其進行確認。 (這將取決于確認模式。默認的自動確認將在使用者獲取消息時發送ACK。對于更重要的消息處理,您可能希望使用“客戶端”確認,其中客戶端明確說明何時確認消息,即完成一些處理后)。
如果使用者由于某種原因失敗,則任何未確認的消息將重新發送到另一個使用者(如果有),并按照上述相同的處理過程進行。 代理在收到ACK之前不會從其索引中刪除該消息。 因此,這包括使用者級別和網絡級別的故障。 如果即使在消費者被“成功處理”之后,這兩個級別中的任何一個都存在錯誤(請注意,這是非常用例的具體含義,“成功處理”的含義),并且經紀人沒有收到確認,那么經紀人很有可能將重新發送消息。 在這種情況下,您最終可能會在使用者方面產生重復,并且可能會希望實現一個冪等的使用者。 為了擴大消息傳遞的生產者/消費者,無論如何,您都需要有冪等的消費者。
最后要注意的一點:不使用XA事務,JMS不會一次保證消息,也只能一次處理消息。 JMS在一次就可以保證一次傳遞的范圍內,可以將消息標記為“已重新傳遞”,并讓消費者檢查該消息,但是消費者應負責處理多少次(或與冪等消費者過濾掉)。
翻譯自: https://www.javacodegeeks.com/2016/05/message-durability-activemq-5-x.html
activemq消息持久化
總結
以上是生活随笔為你收集整理的activemq消息持久化_ActiveMQ 5.x中的消息持久性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux hadoop环境配置(lin
- 下一篇: kn95需要备案吗(KN95备案)