爲什麼我們需要消息隊列?

在這期中,我們將深入探討一種廣泛使用的中間件:消息隊列。

消息隊列有着悠久的歷史,它們經常用於不同系統之間的通信。圖 1 通過將其與星巴克的工作方式進行比較,闡述了消息隊列的概念。

在星巴克,收銀員接受訂單並收取款項,然後在咖啡杯上寫下顧客的名字,交給下一個步驟。製作咖啡的人拿起訂單和杯子,然後製作咖啡。然後顧客在櫃檯上取走咖啡。這三個步驟是異步進行的。收銀員只是將訂單以咖啡杯的形式放下,並不等待完成。製作咖啡的人只是將完成的咖啡放在櫃檯上,並不等待顧客來取。

當您在星巴克下訂單時,收銀員接受訂單並在杯子上寫下您的名字,然後轉向下一個顧客。然後咖啡師拿起杯子,準備您的飲品,然後留下供您取走。這個過程之所以美妙,是因爲每個步驟都是獨立運作的。這很像一個異步系統。

 

圖 1 星巴克作爲消息隊列的類比

這種異步處理,每個步驟都不必等待前一個步驟完成,顯著增加了系統的吞吐量。例如,收銀員不必等待您的飲品製作完成後才接受另一個訂單。

消息隊列的一個示例

現在,讓我們將焦點轉向一個真實世界的例子:電子商務中的限時搶購。由於用戶活動激增,限時搶購可能會給系統帶來壓力。爲了應對這種需求,採用了許多策略,而消息隊列通常在後端優化中發揮關鍵作用。

一個簡化的電子商務限時搶購架構如圖 2 所示。

步驟 1 和 2:顧客向訂單服務下訂單。

步驟 3:在處理付款之前,訂單服務保留所選的庫存。

步驟 4:然後訂單服務將支付指令發送到支付服務。支付服務會扇出到 3 個服務:支付渠道、通知和分析。

步驟 5.1 和 6.1:支付服務將支付指令發送到支付渠道服務。支付渠道服務與外部 PSP(支付服務提供商)進行通信,以完成交易。

步驟 5.2 和 6.2:支付服務向通知服務發送通知,通知服務然後通過電子郵件或短信向顧客發送通知。

步驟 5.3:支付服務向分析服務發送交易詳細信息。

 

圖 2 一個簡化的電子商務限時搶購架構

這裏的一個關鍵點是,在限時搶購活動中,無縫的用戶體驗至關重要。爲了在高流量情況下保持服務的響應能力,可以在多個階段集成消息隊列,以確保性能最佳。

消息隊列的優勢

扇出

支付服務將數據發送到三個下游服務,用於不同的目的:支付渠道、通知和分析。這種扇出方法就像有人在房間裏大聲喊話;誰需要聽到,就聽到了。生產者只需將消息放在隊列中,而消費者可以按照自己的節奏處理消息。

異步處理

借用星巴克的類比,就像收銀員不必等待咖啡製作完成一樣,訂單服務也不必等待支付完成。支付指令被放置在隊列中,一旦完成,顧客就會收到通知。

速率限制

在限時搶購活動中,可能會有數以萬計的併發用戶同時下訂單。在滿足渴望購買的顧客和保持系統穩定之間取得平衡非常重要。一種常見的方法是在特定的時間範圍內限制進入的請求數量,以匹配系統的容量。多餘的請求可能會被拒絕或要求在短時間延遲後重試。這種方法確保系統保持穩定,不會被壓垮。對於成功通過的請求,消息隊列確保它們被高效有序地處理。如果系統的某個部分暫時滯後,訂單不會丟失。它會在隊列中保持,直到可以處理爲止。這確保了即使在壓力下也能保持流暢的流程。

解耦

我們的設計在多個地方使用了

消息隊列。總體架構與圖 2 中呈現的簡化版本不同。服務之間通過定義良好的消息接口進行交互,而不是緊密依賴彼此。每個服務都可以獨立進行修改和部署。每個組件可以使用不同的編程語言進行開發。這爲架構設計帶來了靈活性。

橫向擴展

由於服務被解耦,我們可以根據需求獨立地進行擴展。每個服務可以在不同的能力範圍內提供服務,因此我們可以根據其計劃的每秒查詢數(QPS)或每秒事務數(TPS)進行擴展。

消息持久性

消息隊列還可以用作存儲消息的中間件。如果上游服務崩潰,下游服務始終可以從消息隊列中獲取消息進行處理。通過這種方式,恢復功能從每個服務中移出,併成爲消息隊列的責任。

批處理

在處理流程中,有時我們需要對數據進行批處理以獲得摘要。例如,當支付服務向分析服務發送更新時,分析服務不需要執行實時更新,而是設置一個滾動窗口以批處理處理。批處理是下游服務的要求,因此支付服務不需要知道它,只需將消息放入隊列中。

消息排序

在限時搶購中,庫存數量有限。例如,限時搶購只提供 10 部 iPhone,但有超過 10,000 名下訂單的用戶。我們如何決定訂單的順序呢?通過使用消息隊列來保留所有訂單,將會自然形成一個順序:隊列中的前 10 個訂單將獲得 iPhone。

在圖 3 中,我們將所有內容整合在一起,服務通過消息隊列連接並解耦。這樣,架構可以實現更高的吞吐量。

 

圖 3 在限時搶購架構中使用消息隊列

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/eGGDWqAdgyz01Gevs--tEg