消息隊列如何解決消息積壓問題


 

轉載:消息隊列消息積壓了怎么辦?

作者: 以夢為碼 

  Q:剛開始是對這個疑問抱有質疑態度的,因為使用消息隊列的其中目的就是削峰填谷,來避免高流量時,對下游服務的沖擊,所以使用消息隊列進行緩沖,下游根據自己的消費能力去消費,

我感覺這就是消息積壓本就是使用消息隊列的功能,怎么會是問題呢?

  A:首先消息積壓是正常現象,但凡是過多就不正常了。積壓越來越多就需要處理了。就像一個水庫,日常蓄水是正常的,但下游泄洪能力太差,導致水庫水位一直不停的上漲,這個就不正常了。

 

  消息發送主要涉及三方:producer/consumer/broker,所以發生消息積壓要從這三方來看。

  1、broker

  其實不用太關注消息隊列,因為消息隊列本身的處理能力要遠遠大於業務系統的處理能力。主流消息隊列的單個節點,消息收發的性能可以達到每秒鍾處理幾萬至幾十萬條消息的水平,還可以通過水平擴展 Broker 的實例數成倍地提升處理能力。

 

  2、producer端性能優化

  producer端對消息積壓的影響不大,但是對producer端發送消息的性能有要求。一般是先執行自己的業務邏輯,最后再發送消息。如果說,你的代碼發送消息的性能上不去,你需要優先檢查一下,是不是發消息之前的業務邏輯耗時太多導致的。

  對於發送消息的業務邏輯來說,設置批量發送及批量發送的大小可以提高發送端的發送性能

   Producer 發送消息的過程,Producer 發消息給 Broker,Broker 收到消息后返回確認響應,這是一次完整的交互。假設這一次交互的平均時延是 1ms,我們把這 1ms 的時間分解開,它包括了下面這些步驟的耗時:發送端准備數據、序列化消息、構造請求等邏輯的時間,也就是發送端在發送網絡請求之前的耗時;發送消息和返回響應在網絡傳輸中的耗時;Broker 處理消息的時延。如果是單線程發送,每次只發送 1 條消息,那么每秒只能發送 1000ms / 1ms * 1 條 /ms = 1000 條 消息,這種情況下並不能發揮出消息隊列的全部實力。

  無論是增加每次發送消息的批量大小,還是增加並發,都能成倍地提升發送性能。至於到底是選擇批量發送還是增加並發,主要取決於發送端程序的業務性質。

  發生消息積壓后,producer端服務降級,關閉一些非核心業務,減少消息的產生。

 

  3、consumer端性能優化

  發生消息積壓,主要原因就是消費端的消費能力跟不上生產端的生產速度。

  擴容方案:利用臨時消費者,消費原來積壓隊列中的消息。該消費者不做任何耗時的操作,將消息均勻寫入新創建的隊列里。將更多consumer部署到更多的機器上消費新創建隊列上的消息。

 

  等待積壓的消息被消費,恢復到正常狀態,撤掉擴容服務器。

沒有擴容前:

 

 擴容后:

 


免責聲明!

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



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