天天看點

RocketMq怎麼保證消息不丢失Producer發送消息階段Broker處理消息階段Consumer消費消息階段歸納 

目錄

Producer發送消息階段

手段一:提供SYNC的發送消息方式,等待broker處理結果。

手段二:發送消息如果失敗或者逾時,則重新發送。

手段三:broker提供多master模式

總結

Broker處理消息階段

手段四:提供同步刷盤的政策【等待刷盤成功才會傳回producer成功】

手段五:提供主從模式,同時主從支援同步雙寫

總結

Consumer消費消息階段

手段六:consumer預設提供的是At least Once機制

手段七:消費消息重試機制

總結

RocketMq怎麼保證消息不丢失Producer發送消息階段Broker處理消息階段Consumer消費消息階段歸納 

Producer發送消息階段

發送消息階段涉及到Producer到broker的網絡通信,是以丢失消息的幾率一定會有,那RocketMQ在此階段用了哪些手段保證消息不丢失了(或者說降低丢失的可能性)。

手段一:提供SYNC的發送消息方式,等待broker處理結果。

RocketMQ提供了3種發送消息方式,分别是:

同步發送:Producer 向 broker 發送消息,阻塞目前線程等待 broker 響應 發送結果。

異步發送:Producer 首先建構一個向 broker 發送消息的任務,把該任務送出給線程池,等執行完該任務時,回調使用者自定義的回調函數,執行處理結果。

Oneway發送:Oneway 方式隻負責發送請求,不等待應答,Producer隻負責把請求發出去,而不處理響應結果。

我們在調用producer.send方法時,不指定回調方法,則預設采用同步發送消息的方式,這也是丢失幾率最小的一種發送方式(但是效率比較低)。

手段二:發送消息如果失敗或者逾時,則重新發送。

發送重試源碼如下,本質其實就是一個for循環,當發送消息發生異常或逾時的時候重新循環發送。預設重試3次,重試次數可以通過producer指定。

手段三:broker提供多master模式

即使某台broker當機了,保證消息可以投遞到另外一台正常的broker上。

如果broker隻有一個節點,則broker當機了,即使producer有重試機制,也沒用(Broker都挂了,哪來的重試機制),是以利用多主模式,當某台broker當機了,換一台broker進行投遞,保持高可用。

總結

producer消息發送方式雖然有3種,但為了減小丢失消息的可能性盡量采用同步的發送方式,同步等待發送結果,利用同步發送+重試機制+多個master節點,盡可能減小消息丢失的可能性。

Broker處理消息階段

手段四:提供同步刷盤的政策【等待刷盤成功才會傳回producer成功】

public enum FlushDiskType { SYNC_FLUSH, //同步刷盤 ASYNC_FLUSH//異步刷盤(預設) }

我們知道,當消息投遞到broker之後,會先存到page cache【頁面緩存】,然後根據broker設定的刷盤政策是否立即刷盤,也就是如果刷盤政策為異步,broker并不會等待消息落盤才傳回producer一個成功的消息,也就是說當broker所在的伺服器突然當機,則會丢失部分頁的消息。同步刷盤的政策【等待刷盤成功才會傳回給producer一個成功的消息】

解釋:

同步刷盤:當資料寫入到記憶體中之後立刻刷盤(同步的将記憶體中的資料持久化到磁盤上),在保證刷盤成功的前提下響應一個消息給Producer。

異步刷盤:資料寫入記憶體後,直接響應一個消息給Producer。異步将記憶體中的資料持久化到磁盤上。

手段五:提供主從模式,同時主從支援同步雙寫

        即使broker設定了同步刷盤,如果主broker磁盤損壞,也是會導緻消息丢失。 是以可以給broker指定slave,同時設定master為SYNC_MASTER,然後将slave設定為同步刷盤政策。

此模式下,producer每發送一條消息,都會等消息投遞到master和slave都落盤成功了,broker才會當作消息投遞成功,進而保證休息不丢失。

總結

在broker端,消息丢失的可能性主要在于刷盤政策和同步機制。

RocketMQ預設broker的刷盤政策為異步刷盤,如果有主從,同步政策也預設的是異步同步,這樣子可以提高broker處理消息的效率,但是會有丢失的可能性。是以可以通過同步刷盤政策+同步slave政策(slave也可以進行刷盤)+主從雙寫的方式解決丢失消息的可能。

Consumer消費消息階段

手段六:consumer預設提供的是At least Once機制

        從producer投遞消息到broker,即使前面這些過程保證了消息正常持久化,但如果consumer消費消息沒有消費到也算是消息的丢失。是以RockerMQ預設提供了At least Once機制保證消息可靠消費。

何為At least Once?

Consumer先pull【主動拉取Broker中的資訊】 消息到本地,消費完成後,才向伺服器傳回ack(消費成功的消息--acknowledge)。

通常消費消息的ack機制一般分為兩種思路:

1、先送出後消費;

2、先消費,消費成功後再送出【這個更穩當】;

思路一可以解決重複消費的問題但是會丢失消息,是以Rocketmq預設實作的是思路二,由各自consumer業務方保證幂等(通過給每個消息攜帶一個唯一辨別資訊,去資料庫進行判斷。或者在producer的時候就存儲一個唯一辨別(消息),消費成功删除redis中的消息確定不被重複消費。)來解決重複消費問題。

手段七:消費消息重試機制

        當消費消息失敗了,如果不提供重試消息的能力,則也不能算完全的可靠消費,是以RocketMQ本身提供了重新消費消息的能力。

總結

consumer端要保證消費消息的可靠性,主要通過At least Once+消費重試機制保證。

RocketMq怎麼保證消息不丢失Producer發送消息階段Broker處理消息階段Consumer消費消息階段歸納 

歸納 

MQ主要包含了4個元件 nameserver broker producer consumer

然後如何保證消息不丢失又需要對三個消息階段進行保證

Producer發送消息階段

1通過采用同步發送消息到broker,等待broker接收到消息過後傳回的一個确認消息,雖然效率低,但是時丢失幾率最小的方式,異步1和單向消息發送丢失的幾率比同步消息丢失的幾率大。

2發送消息失敗或逾時則進行重試。

3broker提供多master模式【即使某台broker當機了,換一台broker進行投遞,保持高可用】

===》采用同步消息和失敗重試和多master模式

Broker處理消息階段

手段四:提供同步刷盤的政策【等待刷盤成功才會傳回producer成功】

當資料寫入到記憶體中之後立刻刷盤(同步的将記憶體中的資料持久化到磁盤上),

手段五:提供主從模式,同時主從支援同步雙寫

主從broker都同步刷盤成功,才傳回producer一個确認消息。

===》采用同步刷盤+broker主從模式,支援同步雙寫

Consumer消費消息階段

consumer預設提供的是At least Once機制

手段6 broker隊列中的消息消費成功,才傳回一個确認消息給broker。

手段7 當消息消費失敗了,進行消費消息重試機制(保證幂等就行了。)

===》采用先消費,在傳回一個确認消息+消息重試。