標籤:

消息隊列怎樣不丟消息?

消息隊列的可用性的一個體現就是防止消息丟失,實現消息的必達性。

MQ核心架構

這張圖上畫出了三個角色:發送方,MQ,接收方。

發送方包括兩部分:業務調用方MQ-client-sender,後者向前者提供了兩個API:

  1. SendMsg(bytes[] msg):發送消息,步驟1
  2. SendCallback():發送成功後的回調,步驟3

藍色的MQ核心集群又分為四個部分:MQ-server,zk,db,管理後台web

接收方包括兩部分,業務接收方MQ-client-receiver,後者向前者提供了兩個API:

  1. RecvCallback(bytes[] msg):收到消息回調,步驟4
  2. SendAck():確認收到消息,步驟5

MQ是解耦利器,其工作過程可分成兩大部分

  1. 上半場:發送方將消息投遞給MQ
  2. 下半場:MQ把消息投給給接收方

上半場的消息必達性,是指消息從發送方client必達MQ-server

1)消息從client發送到MQ-server,發送方調用API是SendMsg(bytes[] msg)

2)MQ-server接收到消息後存儲,視為發送成功

3)MQ-server向client發送應答消息,發送方接收後調用SendCallback()

下半場的消息必達性,是指消息從MQ-server必達消息接收方

4)MQ-server將消息發送給接收方,接收方調動API:RecvCallback(bytes[] msg)

5)接收方接到消息後,向MQ-server發送應答消息,調用API:SendAck()

6)MQ-server接收到應答消息後,刪除db中的消息

MQ消息的必達性是怎麼實現的?或者說,MQ丟失了消息怎麼辦?

MQ利用超時-重發機制,保證MQ消息的必達性。

上半場的3個步驟中,如果丟失消息導致超時,那麼MQ-client-sender內的timer會重發,並希望收到3的消息。如果重試N此之後讓不能收到應答消息,那麼SendCallback回調發送失敗。

下半場的3個步驟中,如果丟失消息導致超時,那麼MQ-server內的timer會重發,希望得到5並且執行6,這個過程會採用指數退避原則,先隔x秒重發,2x秒重發,4x秒重發。

以上,可以看到MQ為了保證消息必達,架構上有兩個特點

  1. 消息收到先落地
  2. 消息超時、重傳、確認保證消息必達

2018-01-02閱:

今天讀書,MQ向消費者重發消息只是在push模式下,在pull模式下是不會的。那麼在這種模式下怎樣保證消息必達呢?

參考資料:

消息匯流排能否實現消息必達?

《大型網站系統與Java中間件實踐》


推薦閱讀:

Python操作rabbitmq系列(二):多個接收端消費消息
消息隊列的冪等性
Spring 整合JMS 基於ActiveMQ 實現消息的發送接收
調用:RPC MQ

TAG:消息隊列 |