RabbitMQ/RocketMQ/Kafka 消息順序

RabbitMQ

RabbitMQ 無法做到消息有序的原因:

1.RabbitMQ支持一個隊列多個消費者進行消費,並行處理消息無法保證順序。

2.RabbitMQ支持重試及超時重試機制,這也是導致無法順序消費的原因(即使只有一個隊列一個消費者 )。

RocketMQ

RabbitMQ 實現順序消費:

1.需要有序的消息投入相同的隊列,同時只有一個線程消費(但這個也無法100%解決,重試機制是個坑)。

2.RocketMQ只能保證消息的局部有序,無法保證全局有序。

3.RocketMQ 提供兩種消費模式,一種是並行消費模式,另一種是順序消費模式。當需要順序消費時,只有保證需要保證順序的消息進入同一個隊列(指定隊列),同時設置爲順序消費模式。

4.當設置爲順序消費模式時,消費方式會變成單線程模式,隊列上鎖。當消費失敗時,當前線程會等待一個指定時間,然後再嘗試消費這個消息。這個過程會無限次嘗試直至消費成功。所以業務方需要做一定失敗處理,當失敗次達到一定次數,要返回SUCCESS,否則會一直卡在當前消息。

5.但也有個缺陷,在多主從的情況下,無法保證順序消費。原因是多從的情況下,master之間互不通訊,當master宕機之後,消息會發往“活”的master,消費者也可能會轉移消費其他“活”master對於的隊列。

Kafka

Kafka 實現順序消費:

1.Kafka 通過分區和多副本保證消息順序,同時一個分區只能有一個消費者來消費,來保證消費順序。

2.順序消費的條件,將需要順序消費的消息 通過 key 投入同一個分區。只要分區數量不變,Kafka就保證同一個key的消息,會被投入相同的分區(主分區宕機,會從副本中選舉新的主分區)。( 且kafka 不支持重試)

總結

1.RocketMQ 和 RobbitMQ 想要實現消息的順序消費,只能通過將消息投遞的相同隊列,同時只有一個消費者進行消費。但這樣仍然無法100%保證,重試機制會將消息順序打亂。

2.Kakfa 通過消息投入同一個分區,同時一個分區只會被一個消費者消費,來保證消費順序。其主要實現的原理,一是Kafka保證了每個分區只能被一個消費者消費,二是Kafka實現一主多從機制,確保主分區至少和部分副分區同步,當主分區宕機,從重新選擇"最新"的副分區做主分區,從而保證消費狀態一致。

3.需要保證消息順序的一致性,必定會限制消費速度,這時候可能通過業務技巧來提高消費速度(比如訂單業務,可以將隊列指定爲 訂單號%100, 開啓100個消費者,分佈訂閱這一百個隊列)。

參考

1.狸貓技術窩 RocketMQ系列

2.《深入理解Kafka:核心設計與實踐原理》

3.《RabbitMQ實戰》

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