簡述消息隊列在電商系統使用場景以及工作模式
- 2021 年 11 月 18 日
- 筆記
概述
消息隊列(Message Queue),是分散式系統中重要的組件,是一種進程間通訊或者是同一進程的不同執行緒的通訊方式。和 http 同步協議不同的是,消息隊列是一種非同步的通訊協議,不需要立即獲得結果。
消息隊列的使用場景
- 非同步處理
- 流量控制
- 應用解耦
應用解耦
消息隊列的一個作用就是實現系統應用之間的解耦。舉例一下電商系統的中的訂單系統。
當創建一個訂單時:
- 發起支付
- 扣減庫存
- 發消息告知用戶
- 更新統計數據
這些訂單下游的系統都需要實時獲得訂單數據,隨著業務量的增大和業務的變更,有一段時間不需要發消息給客戶,或者需要添加功能,每次都需要不斷的調式訂單系統和下游系統。
引入消息隊列後,訂單服務在創建訂單時發送一條資訊到消息隊列主題 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
- 每個消息可以被多個隊列消費