[分散式][高併發]訊息佇列的使用場景、概念、常見問題及解決方案

加瓦一枚發表於2019-02-21

MQ(訊息佇列)在軟體架構中是經常被使用的,特別是在分散式系統中也是使用頻率很高的元件。

 

以下從訊息佇列的使用場景、概念、常見問題及解決方案來詳細講解。

 

 

一、訊息佇列使用場景

 

1.1 常見的使用場景

 

系統解耦

在分散式環境下,系統間的相互依賴,最終會會導致整個依賴關係混亂,特別在微服務環境下,會出現相互依賴,甚至是迴圈依賴的情況,對後期系統的拆分和優化都帶來極大負擔。那麼我們就可以用MQ來進行處理。上游系統將資料投遞到MQ,下游系統取MQ的資料進行消費,投遞和消費可以用同步的方式處理,因為MQ接收資料的效能是非常高的,不會影響上游系統的效能。

 

非同步處理

如果採用同步的方式,系統的效能(併發量,吞吐量,響應時間)會有瓶頸。如何解決這個問題呢?引入訊息佇列,將不必要的業務邏輯非同步處理。

 

非同步處理也可以引來 並行處理的使用姿勢。在工作中,我們基於訊息開發了一個簡單的分散式任務處理元件。該元件簡單分為三塊分別是 切分、載入、執行三個階段

 

每個階段都是以作為消費者,然後處理完畢後再作為生產者傳送訊息。訊息消費無狀態,可以按需無限拓容。

 

流量削峰

由於使用訊息,我們的鏈路變成了生產者傳送訊息,訊息中介軟體儲存訊息,最後消費者從訊息中介軟體拉取訊息的一個過程。而訊息中介軟體的儲存能力能夠有效的幫助消費者進行緩衝。試想下,正常流量下消費者能夠愉快的進行消費,瞬時高峰流量來的時候,消費者消費能力跟不上,剛好阻塞在訊息中介軟體,等峰值過後,消費者又能很快的將阻塞的訊息進行消費。

 

流量削鋒也是訊息佇列中的常用場景,一般在秒殺或團搶活動中使用廣泛!

 

資料分發

大部分開源的MQ中介軟體基本都支援一對多或者廣播的模式,而且都可以根據規則選擇分發的物件。這樣上游的一份資料,眾多下游系統中,可以根據規則選擇是否接收這些資料,這樣擴充套件性就很強了。

 

1.2 訊息使用的先決條件

 

以上四種是MQ中介軟體最常見的場景,但是我們細想,MQ中介軟體的引入會帶來什麼問題呢?那就是實時性。所以MQ中介軟體使用的先決條件是:能容忍延遲,只要求最終一致性較為合適。

 

二、訊息相關的概念

 

MQ特點

  • 先進先出
    不能先進先出,都不能說是佇列了。訊息佇列的順序在入隊的時候就基本已經確定了,一般是不需人工干預的。而且,最重要的是,資料是隻有一條資料在使用中。 這也是MQ在諸多場景被使用的原因。

  • 釋出訂閱
    釋出訂閱是一種很高效的處理方式,如果不發生阻塞,基本可以當做是同步操作。這種處理方式能非常有效的提升伺服器利用率,這樣的應用場景非常廣泛。

  • 持久化
    持久化確保MQ的使用不只是一個部分場景的輔助工具,而是讓MQ能像資料庫一樣儲存核心的資料。

  • 分散式
    在現在大流量、大資料的使用場景下,只支援單體應用的伺服器軟體基本是無法使用的,支援分散式的部署,才能被廣泛使用。而且,MQ的定位就是一個高效能的中介軟體。

 

在JMS標準中,有兩種訊息模型P2P(Point toPoint)和Publish/Sub(Pub/Sub)。

 

P2P

點對點,一個發,一個消費。涉及到的角色 釋出者(Publisher)、消費者(Consumer)、訊息佇列(Queue)

 

特點

  1. 一個訊息只能被一個消費者消費,消費後會從佇列裡移除

  2. 釋出者和消費者無關係,釋出者傳送訊息的行為不會隨消費者而改變

  3. 消費者消費完成訊息,需要向佇列Ack,訊息佇列發現訊息消費成功即做訊息移除

 

 

Pub/Sub

釋出訂閱模式,一個釋出,多方訂閱。涉及到的角色有 釋出者(Publisher)、主題(Topic)、訂閱者(Subscriber)。

 

特點

  1. 每個訊息可以有多個消費者

  2. 針對某個主題(Topic)的訂閱者,必須建立一個訂閱者之後,才能消費釋出者的訊息

  3. 為了消費訊息,訂閱者必須保持執行的狀態

 

三、常見問題及解決方案

 

訊息阻塞

1、訊息阻塞一般都是流量激增,超過消費者消費能力;

2、或者消費者出現邏輯問題,導致不斷的重試或長時間等待。

 

第一種可以通過擴容解決

第二種只能緊急修復問題,釋出上線,在阻塞的過程中會造成大量的訊息積壓,這種情況也可以考慮臨時擴容

 

重複消費

重複消費一般發生下消費端,比如消費者處理完畢,在準備進行ack的時候出現了問題,應用重啟後,訊息中介軟體以為該訊息還未處理又推給了消費者,或者消費者拉取的時候重複。

一般的做法是消費端做冪等。

 

訊息丟失

訊息丟失一般分為生產者傳送失敗、訊息中介軟體丟失、消費丟失。

生產者丟失:可能以為網路問題或者訊息中間處理失敗導致,訊息遺漏。

訊息中間的丟失:一般中介軟體可以設定丟棄策略,大部分MQ中介軟體產品可以保證資料不丟失,這種情況基本不用考慮。

消費丟失:有的訊息中介軟體支援自動ack,當消費者消費到訊息,訊息中介軟體也不管是否消費成功自動ack。這時候一般選擇消費者主動ack比較合適。

 

訊息順序性

訊息順序性一般通過MQ中介軟體保證,大部分MQ中介軟體只能做到區域性有序,比如Kafka,只能保證單個partition佇列有序。有些也會做到全域性有序,但是成本比較高。筆者目前服務的公司現在是支援全域性有序的。

 

MQ元件有activeMQ、rabbitMQ、rocketMQ、zeroMQ、Kafka;有興趣的同學可以深入去了解。

相關文章