RocketMQ知識盤點【叄】_Consumer

前文回顧:

RocketMQ知識盤點【壹】_Producer和NameServer

RocketMQ知識盤點【貳】_Broker和消息存儲

 

1.模式

1.1 模式類型

分爲推模式和拉模式。

推模式是broker向consumer註冊一個listener接口,收到消息後會回調listener接口,採用長輪詢方式實現push;

拉模式是consumer主動向broker拉消息,下文介紹。本質上,推模式是在拉模式上包裝了一層,一個拉取任務完成後開始下一個拉取任務。

簡短截說,拉模式下consumer端會使用PullMessageService(本質是一個線程),不斷構造PullRequest到pullRequestQueue,經歷負載均衡向broker發送拉取消息請求。每次默認拉取32個消息,存放到ProcessQueue中,當消息消費成功再從中移除。默認情況消息超過15分鐘未消費成功,則延遲3個延遲級別進行重試。

推模式是基於拉模式實現的,在於PullRequest完成一次拉取消息任務後,又再次把它放回pullRequestQueue中,實現循環請求拉取。如果consumer向broker發送消息拉取請求後,沒有消息到達消費隊列:

如果未啓用長輪詢機制,則毀在服務端等待shortPollingTimeMills(掛起)後再判斷消息是否到達消息隊列,如果消息仍未到達則提示消息不存在(PULL_NOT_FOUND)。

如果啓動長輪詢機制,一方面會每10s檢查消息是否到達,同時一有新消息到達馬上通知掛起線程再次驗證新消息是否感興趣,如果不是則繼續等待直到掛起超時(默認15s)。

長輪詢模式通過longPollingEnable=true設置。

 

1.2 比較

推模式:broker負責消息存儲、處理請求、推送狀態等

優點是實時性好;缺點是如果push能力大於消費能力,則可能造成消費者掛掉或消息丟失;

 

拉模式:consumer除了消費消息還要保存偏移量,以及異常場景下消息緩存等

優點是拉取頻率可以自己決定;缺點是可能造成broker消息堆積;

 

2 負載均衡

消息的分配遵循一個原則:一個consumer可以消費多個messageQueue,但是一個messageQueue只能分配給一個consumer消費。rocketMq共提供了5種分配算法:

1.AllocateMessageQueueAveragely:平均分配;

2.AllocateMessageQueueAveragelyByCircle:平均輪詢分配;

3.AllocateMessageConsistentHash:一致性哈希;

4.AllocateMessageQueueByConfig:自定義配置;

5.AllocateMessageQueueByMacheRoom:根據broker機房名。

注意,基於上面的原則,當consumer數量大於messageQueue數量時,會有一部分consumer無法消費消息。

 

3 順序消息

rocketMQ不保證一個topic下的所有messageQueue消息順序性,但可以保證一個messageQueue下消息的順序性。

 

4 延時消息

RocketMQ不支持自定義延時,目前共支持18個延時等級,分別爲

1s,5s,10s,30s,1min,2min,3min,4min,5min,6min,7min,8min,9min,10min,20min,30min,1h,2h

在每個broker有一個默認topic,叫SCHEDULE_TOPIC_XXXX,這個topic下共有18個messageQueue,queueId從0到17,分別對應這18個延遲等級。同時對每個messageQueue設置一個定時任務,每隔1s到對應的messageQueue從最近一次處理的offset開始撈取要處理的消息,根據消息的物理偏移量和長度到commitLog裏拿到完整消息體,然後構造出新的消息順序寫入commitLog,再將其投入到相應的messageQueue中去。

 

5 消息重試

集羣模式下,消息的消費進度保存在broker(廣播模式broker把消息廣播出去就不負責了)。如果consumer返回RECONSUME_LATER,則broker啓動消息重試機制。先將消息的topic和messageQueue保存到消息屬性,然後將此消息存儲到SCHEDULE_TOPIC_XXXX相應的延遲級別隊列中。當到達重試時間後,該消息會被投入到topic爲“%RETRY%消費者組名”的隊列中,每臺broker只會爲同一個消費者組創建一個重試隊列。“%RETRY%消費者組名”這個topic,在concumer啓動的時候已經自動關注,所以當後面consumer來拉取消息時,會直接將重試消息拉走消費。

最佳實踐:建議不要依賴rocketMQ的消息重試,可以自己在應用通過延時消息完成延時消息重試。

 

6 死信隊列

當一條消息重試16次仍然失敗,則進入死信隊列,topic爲“%DLQ%消費者組名”。不再被消費,需要人工處理。這裏注意,每次重試消息延遲級別不是delayLevel++的,而是有一套根據重試次數的算法。

 

7 消息過濾

可以通過配置,使用消息的tag或表達式過濾。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章