阿里消息中間件ONS消息亂序問題(二)

順序消息:消息的有序是 消息消費時,可以按照發送的順序進行消費。服務器

例如:假如生產者產生的兩條消息M1 、M2 要保證兩條消息的順序來消費應該怎麼作,咱們可能想到這樣的場景:網絡

M1發送到S1 , M2發送到S2,若是保證M1先於M2被消費,須要M1到達消費端後,通知S2 , 而後S2再將消息M2發送到消費端。設計

這個模式存在的問題是:若是M1,M2分別發送到兩臺Server,因爲兩臺Server服務器的網絡環境可能不一樣,因此,不能保證M1先到達, 因此也就不能保證M1先被訂閱者消費。那麼就要在MQServer集羣維護消息的順序,如何解決:其中一種解決方式是把消息發送到同一臺消息服務器上。隊列

這樣能夠保證M1先於M2到達MQServer(客戶端等到M1發送成功後再發送M2),根據先到達先消費的原則,M1會先於M2被消費,能保證順序。效率

這個模型,理論上能夠保證消息的順序,但實際運行中你可能會遇到下面問題。集羣

只要將消息從一臺服務器發往另外一臺服務器,就會出現網絡延遲問題,如上圖所示,若是發送M1耗時大於發送M2耗時,那麼M2就先被消費,仍然不能保證消息的順序,即便M1和M2同事到達消費端,因爲不清楚消費端1和消費端2的負載狀況,仍然有可能出現M2先於M1被消費。如何解決這個問題? 將M1和M2發往同一個消費者便可。且發送M1後,須要消費端響應成功後才能發送M2。並行

可是會引入另一個問題,若是發送M1後,消費端1沒響應,那是繼續發送M2呢 仍是從新發送M1?通常爲了保證消息必定被消費,確定會選擇重發M1到另一個消費端2,以下所示:方法

這樣的模型就能保證嚴格的消息順序了,可是消費端1沒有響應Server時有兩種狀況,一種是M1確實沒有到達,另一種狀況是消費端1已響應。可是Server沒收到。若是是第二種狀況,重發M1,就會形成M1被重複消費,也就是咱們所說的 消息重複的問題。im

嚴格的順序消息很是容易理解,並且處理問題也比較容易,要實現嚴格的順序消息,簡單且可行的方法就是:客戶端

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

這樣設計,並行度就成了消息系統的瓶頸(吞吐量不夠),也會致使更多地異常處理,好比:只要消費端出現了問題,就會致使整個處理流程的阻塞,咱們不得不花費更多地經理來解決阻塞問題。

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

世界上解決一個計算機問題字簡單的方法:「剛好」不須要解決它! ——沈詢

有些問題看起來重要,但實際上咱們能夠經過合理的設計或者將問題分解來規避。若是硬要把時間花在解決它們身上,其實是浪費時間,效率 低下的,從這個角度來看消息的順序問題,咱們能夠得出兩個結論:

  1. 不關注亂序的應用實際大量存在
  2. 隊列無序並不意味着消息無序
相關文章
相關標籤/搜索