RocketMQ - 消費者概述

VipSoft發表於2023-02-23

消費流程

image
消費者組: 一個邏輯概念,在使用消費者時需要指定一個組名。一個消費者組可以訂閱多個Topic。
消費者例項: 一個消費者組程式部署了多個程式,每個程式都可以稱為一個消費者例項。
訂閱關係: 一個消費者組訂閱一個 Topic 的某一個 Tag,這種記錄被稱為訂閱關係。RocketMQ規定消費訂閱關係(消費者組名-Topic-Tag)必須一致——在此,筆者想提醒讀者,一定要重視這個問題,一個消費者組中的例項訂閱的Topic和Tag必須完全一致,否則就是訂閱關係不一致。訂閱關係不一致會導致消費訊息紊亂。

消費模式

RocketMQ目前支援叢集消費模式和廣播消費模式,其中叢集消費模式使用最為廣泛

叢集消費模式

在同一個消費者組中的消費者例項,是負載均衡(策略可以配置)地消費Topic中的訊息,假如有一個生產者(Producer)傳送了 120 條訊息,其所屬的 Topic 有 3 個消費者(Consumer)組,每個消費者組設定為叢集消費,分別有2個消費者例項,如圖所示。
image
Consumer Group A 的兩個例項 Consumer Instance A1 和 Consumer Instance A2 分別負載均衡地消費60條訊息。由此我們可以得出使用負載均衡策略時,每個消費者例項消費訊息數=生產訊息數/消費者例項數,在本例中是60=120/2

適用場景: 目前大部分場景都適合叢集消費模式,RocketMQ 的消費模式預設是叢集消費。比如非同步通訊、削峰等對訊息沒有順序要求的場景都適合叢集消費。因為叢集模式的消費進度是儲存在Broker端的,所以即使應用崩潰,消費進度也不會出錯。

廣播消費模式

廣播消費,顧名思義全部的訊息都是廣播分發,即消費者組中的全部消費者例項將消費整個 Topic 的全部訊息。比如,有一個生產者生產了 120 條訊息,其所屬的 Topic 有 3個消費者組,每個消費者組設定為廣播消費,分別有兩個消費者例項,如圖所示。
image
Consumer Group A 的兩個例項 Consumer Instance A1 和 Consumer Instance A2 分別消費120條訊息。整個消費者組收到訊息120×2=240條。由此我們可以得出廣播消費時,每個消費者例項的消費訊息數=生產者生產的訊息數,整個消費者組中所有例項消費訊息數=每個消費者例項消費訊息數×消
費者例項數,本例中是240=120×2

適用場景: 廣播消費比較適合各個消費者例項都需要通知的場景,比如重新整理應用伺服器中的快取,如圖所示。

image
生產者發一個重新整理快取的廣播訊息,消費者組如果設定為廣播消費,那麼每個應用服務中的消費者都可以消費這個訊息,也都能重新整理快取。

廣播消費的消費進度儲存在客戶端機器的檔案中。如果檔案弄丟了,那麼消費進度就丟失了,可能會導致部分訊息沒有消費

可靠消費

RocketMQ是一種十分可靠的訊息佇列中介軟體,消費側透過重試-死信機制、Rebalance機制等多種機制保證消費的可靠性。

重試-死信機制

我們假設有一個場景,在消費訊息時由於網路不穩定導致一條訊息消費失敗。此時是讓生產者重新手動發訊息呢,還是自己做資料補償?

橫向看,RocketMQ的消費過程分為 3個階段:正常消費、重試消費和死信。在引進了正常Topic、重試佇列、死信佇列後,消費過程的可靠性提高了。RocketMQ的消費流程如圖所示
image

正常Topic: 正常消費者訂閱的Topic名字。
重試Topic: 如果由於各種意外導致訊息消費失敗,那麼該訊息會自動被儲存到重試Topic中,格式為“%RETRY%消費者組”,在訂閱的時候會自動訂閱這個重試Topic。

進入重試佇列的訊息有16次重試機會,每次都會按照一定的時間間隔進行。RocketMQ 認為消費不是一錘子買賣,可能由於各種偶然因素導致正常消費失敗,只要正常消費或者重試消費中有一次消費成功,就算消費成功
image

死信Topic: 死信Topic名字格式為“%DLQ%消費者組名”。如果正常消費1次失敗,重試16次失敗,那麼訊息會被儲存到死信Topic中,進入死信Topic的訊息不能被再次消費。RocketMQ認為,如果17次機會都失敗了,說明生產者傳送訊息的格式發生了變化,或者消費服務出現了問題,需要人工介入處理。

Rebalance機制

Rebalance(重平衡)機制,用於在發生Broker掉線、Topic擴容和縮容、消費者擴容和縮容等變化時,自動感知並調整自身消費,以儘量減少甚至避免訊息沒有被消費。後面會詳細講述Rebalance的過程。

死信佇列

當一條訊息初次消費失敗,訊息佇列RocketMQ版會自動進行訊息重試,達到最大重試次數後,若消費依然失敗,則表明消費者在正常情況下無法正確地消費該訊息。此時,訊息佇列RocketMQ版不會立刻將訊息丟棄,而是將其傳送到該消費者對應的特殊佇列中。

在訊息佇列RocketMQ版中,這種正常情況下無法被消費的訊息稱為死信訊息(Dead-Letter Message),儲存死信訊息的特殊佇列稱為死信佇列(Dead-Letter Queue)

死信訊息具有以下特性:

  • 不會再被消費者正常消費。
  • 有效期與正常訊息相同,預設為3天,3天后會被自動刪除。因此,請在死信訊息產生後的3天內及時處理。

死信佇列具有以下特性:

  • 一個死信佇列對應一個Group ID, 而不是對應單個消費者例項。
  • 如果一個Group ID未產生死信訊息,訊息佇列RocketMQ版不會為其建立相應的死信佇列。
  • 一個死信佇列包含了對應Group ID產生的所有死信訊息,不論該訊息屬於哪個Topic。

相關文章