1. 程式人生 > >MQ如何解決訊息的順序問題和訊息的重複問題

MQ如何解決訊息的順序問題和訊息的重複問題

一、摘要

分散式訊息系統作為實現分散式系統可擴充套件、可伸縮性的關鍵元件,需要具有高吞吐量、高可用等特點。而談到訊息系統的設計,就回避不了兩個問題:

1、訊息的順序問題

2、訊息的重複問題

二、關鍵特性以及其實現原理

2.1、順序訊息

要實現嚴格的順序訊息,簡單且可行的辦法就是:

保證生產者 - MQServer - 消費者是一對一對一的關係

這樣的設計雖然簡單易行,但也會存在一些很嚴重的問題,比如:

1、並行度就會成為訊息系統的瓶頸(吞吐量不夠)

2、更多的異常處理,比如:只要消費端出現問題,就會導致整個處理流程阻塞,我們不得不花費更多的精力來解決阻塞的問題。

但我們的最終目標是要叢集的高容錯性和高吞吐量。這似乎是一對不可調和的矛盾,那麼阿里是如何解決的?

有些問題,看起來很重要,但實際上我們可以通過合理的設計或者將問題分解來規避。如果硬要把時間花在解決問題本身,實際上不僅效率低下,而且也是一種浪費。從這個角度來看訊息的順序問題,我們可以得出兩個結論:

1、不關注亂序的應用實際大量存在

2、佇列無序並不意味著訊息無序

2.2、訊息重複

上面在解決訊息順序問題時,引入了一個新的問題,就是訊息重複。那麼MQ是怎樣解決訊息重複的問題呢?還是“恰好”不解決。

造成訊息的重複的根本原因是:網路不可達。只要通過網路交換資料,就無法避免這個問題。所以解決這個問題的辦法就是不解決,轉而繞過這個問題。那麼問題就變成了:如果消費端收到兩條一樣的訊息,應該怎樣處理?

1、消費端處理訊息的業務邏輯保持冪等性

2、保證每條訊息都有唯一編號且保證訊息處理成功與去重表的日誌同時出現

第1條很好理解,只要保持冪等性,不管來多少條重複訊息,最後處理的結果都一樣。第2條原理就是利用一張日誌表來記錄已經處理成功的訊息的ID,如果新到的訊息ID已經在日誌表中,那麼就不再處理這條訊息。

我們可以看到第1條的解決方式,很明顯應該在消費端實現,不屬於訊息系統要實現的功能。第2條可以訊息系統實現,也可以業務端實現。正常情況下出現重複訊息的概率不一定大,且由訊息系統實現的話,肯定會對訊息系統的吞吐量和高可用有影響,所以最好還是由業務端自己處理訊息重複的問題,這也是MQ不解決訊息重複的問題的原因。

MQ不保證訊息不重複,如果你的業務需要保證嚴格的不重複訊息,需要你自己在業務端去重。

三、閱讀原文

原始碼線上演示和解讀