【RabbitMQ】保證消息的不重複消費

1、出現非冪等性緣由
爲保證消息的可達性,超時、重傳、確認機制可能致使消息總線、或者業務方收到重複的消息,從而對業務產生影響。網絡

可靠性投遞機制:好比消息已經發送出去,mq已經收到了,而後mq在返回confirm的時候網絡出現閃斷,致使broker未收到應答,致使發送兩次。
 MQ Broker服務與消費端傳輸消息的過程當中出現網絡抖動。
消費端故障、異常。
2、生產者
imagespa

MQ消息發送上半場,即上圖中的1-3server

1,發送端MQ-client將消息發給服務端MQ-serverrem

2,服務端MQ-server將消息落地it

3,服務端MQ-server回ACK給發送端MQ-clientclass

若是3丟失,發送端MQ-client超時後會重發消息,可能致使服務端MQ-server收到重複消息。cli

 

此時重發是MQ-client發起的,消息的處理是MQ-server,爲了不步驟2落地重複的消息,對每條消息,MQ系統內部必須生成一個inner-msg-id,做爲去重和冪等的依據,這個內部消息ID的特性是:im

(1)全局惟一支付

(2)MQ生成,具有業務無關性,對消息發送方和消息接收方屏蔽總結

 

有了這個inner-msg-id,就能保證上半場重發,也只有1條消息落到MQ-server的DB中,實現上半場冪等。

 

3、消費者
image

MQ消息發送下半場,即上圖中的4-6

4,服務端MQ-server將消息發給接收端MQ-client

5,接收端MQ-client回ACK給服務端

6,服務端MQ-server將落地消息刪除

須要強調的是,接收端MQ-client回ACK給服務端MQ-server,是消息消費業務方的主動調用行爲,不能由MQ-client自動發起,由於MQ系統不知道消費方何時真正消費成功。

若是5丟失,服務端MQ-server超時後會重發消息,可能致使MQ-client收到重複的消息。

 

此時重發是MQ-server發起的,消息的處理是消息消費業務方,消息重發勢必致使業務方重複消費(上例中的一次付款,重複髮卡),爲了保證業務冪等性,業務消息體中,必須有一個biz-id,做爲去重和冪等的依據,這個業務ID的特性是:

(1)對於同一個業務場景,全局惟一

(2)由業務消息發送方生成,業務相關,對MQ透明

(3)由業務消息消費方負責判重,以保證冪等

 

最多見的業務ID有:支付ID,訂單ID,帖子ID等。

 

具體到支付購卡場景,發送方必須將支付ID放到消息體中,消費方必須對同一個支付ID進行判重,保證購卡的冪等。

 

有了這個業務ID,纔可以保證下半場消息消費業務方即便收到重複消息,也只有1條消息被消費,保證了冪等。

 

3、總結
MQ爲了保證消息必達,消息上下半場都可能發送重複消息,如何保證消息的冪等性呢?

上半場

MQ-client生成inner-msg-id,保證上半場冪等。

這個ID全局惟一,業務無關,由MQ保證。

 

下半場

業務發送方帶入biz-id,業務接收方去重保證冪等。

這個ID對單業務惟一,業務相關,對MQ透明。

 

結論:冪等性,不只對MQ有要求,對業務上下游也有要求。

相關文章
相關標籤/搜索