簡述消息隊列在電商系統使用場景以及工作模式

  • 2021 年 11 月 18 日
  • 筆記

概述

消息隊列(Message Queue),是分散式系統中重要的組件,是一種進程間通訊或者是同一進程的不同執行緒的通訊方式。和 http 同步協議不同的是,消息隊列是一種非同步的通訊協議,不需要立即獲得結果。

消息隊列的使用場景

  • 非同步處理
  • 流量控制
  • 應用解耦

應用解耦

消息隊列的一個作用就是實現系統應用之間的解耦。舉例一下電商系統的中的訂單系統。
當創建一個訂單時:

  1. 發起支付
  2. 扣減庫存
  3. 發消息告知用戶
  4. 更新統計數據

這些訂單下游的系統都需要實時獲得訂單數據,隨著業務量的增大和業務的變更,有一段時間不需要發消息給客戶,或者需要添加功能,每次都需要不斷的調式訂單系統和下游系統。

引入消息隊列後,訂單服務在創建訂單時發送一條資訊到消息隊列主題 Order 中,所有的下游都訂閱主題Order,這樣無論增加、減少下游系統還是下游系統的功能如何變化,訂單服務都不需要做更改了,實現了訂單服務和下游服務的解耦。

非同步處理

非同步處理是將很多串列進行的步驟轉成非同步處理,還是已訂單系統為例,下單訂單需要創建訂單和鎖定庫存,確定本次請求後馬上給用戶返迴響應,然後把後續請求的數據的都在消息隊列,由消息隊列非同步處理。

這樣把五個步驟減少為兩個步驟,假設每個步驟處理時間需要500ms,在不考慮網路延遲的情況下:

串列處理: 500 * 5 = 2500ms
並行處理:500 * 2 = 1000ms

系統響應時間縮短一半以上。這樣響應速度更快,而且把請求放在後續操作,可以充分利用更多的資源處理請求。
所以我們可以看到,實現非同步操作的服務:

  • 更快地返回結果
  • 減少等待時間,提升系統總體性能

流量控制

在購物網站的做一個秒殺活動,平時網站能支撐每秒1000次並發請求,但是電商秒殺一下請求猛增到每秒3000次請求,多出來的請求,可能直接讓系統宕機。
所以我們就需要使用消息隊列來控制流量,當系統短時間接收到大量請求時,會先將請求堆積到消息隊列上,後端服務從消息隊列上消費數據,消息隊列相對於給後端服務做了一次緩衝。

優缺點

上面的概述總結起來有個三個優點:非同步、削峰和解耦。
缺點有以下幾個:

  • 系統可用性降低
  • 增加系統複雜度
  • 可能會數據一致性問題,比如數據丟失,數據重複傳輸

RabbitMQ消息隊列五種工作模式

rabbitmq官網教程上介紹了幾種工作模式,

簡單(simple)模式

The simplest thing that does something

從上面的示意圖看出來 simple 模式有以下幾個特徵:

  • 只有一個生產者、一個消費者和一個隊列
  • 生產者和消費者在發送和接收消息時,只需要指定隊列名稱,而不需要發送那個 Exchange 交換機。

工作(Work)模式


在多個消費者之間分配任務(競爭消費者模式
創建一個工作隊列,添加多個消費者共同消費工作隊列上的任務。每一個消息都給一個消費者消費

發布訂閱(Publish/Subscribe)模式


工作模式中每個消息只能被一個消費者消費,發布訂閱模式是每個消息同時給多個消費者消費。
上圖中的X表示Exchange 交換器,Exchange 類型有:Direct、Topic、Headers和Fanout。

  • 發布訂閱用的是 Fanout
  • Fanout 是不需要指定具體的隊列名,Exchange 會將消息轉發所有的綁定的隊列

路由(Routing)模式


路由模式中的交換器類型為 direct,在同一個交換器,由生產者指定指定目標隊列。

  • 指定規則按照 RoutingKey 指定
  • 消費者通過 BindingKey 綁定自己接收消息隊列
  • 只有 RoutingKey 和 BindingKey 匹配隊列才會收到資訊

RoutingKey 是生產者指定 Exchange 路由到哪個隊列,BindingKey 用於消費者綁定到某個隊列

主題(Topic)模式


主題模式是根據通配符綁定隊列,其中 * 可以替換任務一個標識符,# 可以替換多個標識符,通配符和名稱使用 . 隔開。

  • 主題模式的 Exchange 類型為 topic
  • 每個消息可以被多個隊列消費

參考