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

小碼code發表於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
  • 每個訊息可以被多個佇列消費

參考

相關文章