訊息匯流排真的能保證冪等

2021-08-09 22:04:05 字數 2128 閱讀 9356

一、緣起

如《訊息匯流排訊息必達》所述,mq訊息必達,架構上有兩個核心設計點:

(1)訊息落地

(2)訊息超時、重傳、確認

再次回顧訊息匯流排核心架構,它由傳送端、服務端、固化儲存、接收端四大部分組成。

為保證訊息的可達性,超時、重傳、確認機制可能導致訊息匯流排、或者業務方收到重複的訊息,從而對業務產生影響。

舉個栗子:

購買會員卡,上游支付系統負責給使用者扣款,下游系統負責給使用者發卡,通過mq非同步通知。不管是上半場的ack丟失,導致mq收到重複的訊息,還是下半場ack丟失,導致購卡系統收到重複的購**知,都可能出現,上游扣了一次錢,下游發了多張卡。

訊息匯流排的冪等性設計至關重要,是本文將要討論的重點。

二、上半場的冪等性設計

mq訊息傳送上半場,即上圖中的1-3

1,傳送端mq-client將訊息發給服務端mq-server

2,服務端mq-server將訊息落地

3,服務端mq-server回ack給傳送端mq-client

如果3丟失,傳送端mq-client超時後會重發訊息,可能導致服務端mq-server收到重複訊息。

此時重發是mq-client發起的,訊息的處理是mq-server,為了避免步驟2落地重複的訊息,對每條訊息,mq系統內部必須生成乙個inner-msg-id,作為去重和冪等的依據,這個內部訊息id的特性是:

(1)全域性唯一

(2)mq生成,具備業務無關性,對訊息傳送方和訊息接收方遮蔽

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

三、下半場的冪等性設計

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條訊息被消費,保證了冪等。

三、總結

mq為了保證訊息必達,訊息上下半場均可能傳送重複訊息,如何保證訊息的冪等性呢?

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

這個id全域性唯一,業務無關,由mq保證。

下半場業務傳送方帶入biz-id,業務接收方去重保證冪等。

這個id對單業務唯一,業務相關,對mq透明。

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

訊息佇列 保證訊息消費的冪等

昨天業務反饋了乙個問題,乙個使用者的月流水賬單重複了,拿到userid,開始定位問題之路。檢視資料庫記錄,如下圖,使用者月流水資料確實重複了 taskid同乙個批次,每個月資料都有二條 1.首先,看外部資料 商是否重複推送業務資料給我,我程式中是會設定攔截重複訊息 2.檢視訊息接收,以及訊息推送到m...

訊息冪等 如何保證訊息不被重複消費?

應用的冪等是在分布式系統設計時必須要考慮的乙個方面,如果對冪等沒有額外的考慮,那麼在訊息失敗重新投遞,或者遠端服務重試時,可能會出現許多詭異的問題。一起來看一下,在訊息佇列應用中,如何處理因為重複投遞等原因導致的冪等問題。不同訊息佇列支援的投遞方式 業務上如何處理冪等 首先明確一下,冪等並不是問題,...

mq如何保證訊息的冪等性

一 訊息的傳送流程 二 出現非冪等性的情況 1 生產者已把訊息傳送到mq,在mq給生產者返回ack的時候網路中斷,故生產者未收到確定資訊,生產者認為訊息未傳送成功,但實際情況是,mq已成功接收到了訊息,在網路重連後,生產者會重新傳送剛才的訊息,造成mq接收了重複的訊息 2 消費者在消費mq中的訊息時...