高並發系統設計(十三):消息隊列的三大作用:削峰填谷、異步處理、模塊解耦


原文鏈接:"https://www.cnblogs.com/wt645631686/p/13199532.html

削去秒殺場景下的峰值寫流量

而在秒殺場景下,高並發的寫請求並不是持續的,也不是經常發生的,而只有在秒殺活動開始后的幾秒或者十幾秒時間內才會存在。為了應對這十幾秒的瞬間寫高峰,將秒殺請求暫存在消息隊列中,然后業務服務器會響應用戶“秒殺結果正在計算中”,釋放了系統資源之后再處理其它用戶的請求。

在后台啟動若干個隊列處理程序,消費消息隊列中的消息,再執行校驗庫存、下單等邏輯。因為只有有限個隊列處理線程在執行,所以落入后端數據庫上的並發請求是有限的。而請求是可以在消息隊列中被短暫地堆積,當庫存被消耗完之后,消息隊列中堆積的請求就可以被丟棄了。

 

 

這就是消息隊列在秒殺系統中最主要的作用:削峰填谷,也就是說它可以削平短暫的流量高峰,雖說堆積會造成請求被短暫延遲處理,但是只要時刻監控消息隊列中的堆積長度,在堆積量超過一定量時,增加隊列處理機數量,來提升消息的處理能力就好了,而且秒殺的用戶對於短暫延遲知曉秒殺的結果,也是有一定容忍度的。

這里需要注意一下,所說的是“短暫”延遲,如果長時間沒有給用戶公示秒殺結果,那么用戶可能就會懷疑你的秒殺活動有貓膩了。所以,在使用消息隊列應對流量峰值時,需要對隊列處理的時間、前端寫入流量的大小,數據庫處理能力做好評估,然后根據不同的量級來決定部署多少台隊列處理程序,這里要根據平均請求時間和商品秒殺總量來計算,設定處理機的數量。

比如你的秒殺商品有1000件,處理一次購買請求的時間是500ms,那么總共就需要500s的時間。這時,你部署10個隊列處理程序,那么秒殺請求的處理時間就是50s,也就是說用戶需要等待50s才可以看到秒殺的結果,這是可以接受的。這時會並發10個請求到達數據庫,並不會對數據庫造成很大的壓力。

通過異步處理簡化秒殺請求中的業務流程

還是剛才的秒殺場景下,我們在處理購買請求時,需要500ms。分析了一下整個的購買流程,發現這里面會有主要的業務邏輯,也會有次要的業務邏輯:比如說,主要的流程是生成訂單、扣減庫存;次要的流程可能是我們在下單購買成功之后會給用戶發放優惠券,會增加用戶的積分。

假如發放優惠券的耗時是50ms,增加用戶積分的耗時也是50ms,那么如果我們將發放優惠券、增加積分的操作放在另外一個隊列處理機中執行,那么整個流程就縮短到了400ms,性能提升了20%,處理這1000件商品的時間就變成了400s。如果我們還是希望能在50s之內看到秒殺結果的話,只需要部署8個隊列程序就好了。

 

解耦實現秒殺系統模塊之間松耦合

比如數據團隊對你說,在秒殺活動之后想要統計活動的數據,借此來分析活動商品的受歡迎程度等等指標。這時需要將大量的數據發送給數據團隊。

一個思路是:可以使用HTTP或者RPC的方式來同步地調用,也就是數據團隊這邊提供一個接口,我們實時將秒殺的數據推送給它,但是這樣調用會有兩個問題:

  • 整體系統的耦合性比較強,當數據團隊的接口發生故障時,會影響到秒殺系統的可用性。
  • 當數據系統需要新的字段,就要變更接口的參數,那么秒殺系統也要隨着一起變更。

這時可以考慮使用消息隊列降低業務系統和數據系統的直接耦合度。

秒殺系統產生一條購買數據后,我們可以先把全部數據發送給消息隊列,然后數據團隊再訂閱這個消息隊列的話題,這樣它們就可以接收到數據,然后再做過濾和處理了。解耦合之后,數據系統的故障就不會影響到秒殺系統了,同時,當數據系統需要新的字段時,只需要解析消息隊列中的消息,拿到需要的數據就好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM