MQ系列13:訊息大量堆積如何為解決

2023-06-09 18:00:58

MQ系列1:訊息中介軟體執行原理
MQ系列2:訊息中介軟體的技術選型
MQ系列3:RocketMQ 架構分析
MQ系列4:NameServer 原理解析
MQ系列5:RocketMQ訊息的傳送模式
MQ系列6:訊息的消費
MQ系列7:訊息通訊,追求極致效能
MQ系列8:資料儲存,訊息佇列的高可用保障
MQ系列9:高可用架構分析
MQ系列10:如何保證訊息冪等性消費
MQ系列11:如何保證訊息可靠性傳輸
MQ系列12:如何保證訊息順序性

1 背景

我們在前面兩個章節中,介紹了訊息元件如何保證可靠性傳輸和順序行消費,參考上面系列的11、12章節。

  • 比如在訊息生產階段,如何保證訊息發出的穩定性和可靠性;
  • 在訊息伺服器處理階段,如何保證訊息從生產到傳送出去,經過網路傳輸,再到達Broker伺服器並被接收的這整個階段的可靠性,即如何使用ACK機制來保證訊息傳遞的可靠性;
  • 還有就是訊息消費的可靠性,Broker作為訊息伺服器,訊息接收並持久化訊息並消費的整個過程的可靠性如何保障。
    對於訊息佇列元件來說,這幾個步驟出現問題,都有可能造成訊息佇列無法進行正常執行,訊息堆積的情況發生。
    另外一種情況可能就是突發的流量峰值,這種一般發生在某種消費促銷活動或者各種搶購、競拍場景中。

2 原因分析

2.1 訊息生產(Producer)遠超預期

訊息的生產的規模遠超過原來的預期值,成數倍甚至幾十倍的增長,這種產生的原因可能如下:

  1. 比如遇到各種流量衝擊的活動:618、雙11大促、競拍、搶購、秒殺業務。(這種需要做好容量預估管理)
  2. 程式缺陷;死迴圈呼叫、批次請求、記憶體漏失導致的流量飆升問題。(這種需要做好)

2.2 訊息接收和持久化出現故障

Broker伺服器接收訊息並持久化出現問題:服務故障、網路延遲、持久化失敗等,這種情況一般也比較少見...

2.3 訊息消費(Consumer)能力下降致訊息堆積

出現原因可能有如下幾種:

  • 消費失敗時大量重試導致訊息堆積。
  • 消費者程式的故障:如 程式死鎖,io阻塞等。
  • 消費者資源瓶頸:目前的主流訊息佇列,單個節點訊息收發的效能可以達到萬級別甚至10萬級+的水平。除非容量預估沒有做好,一般不會出現這種問題。即使出現這種問題,通過Scale Out Broker 的範例數也是比較輕鬆可以解決的。

3 訊息堆積的解決方案

根據上面的整理,在遇到訊息堆積的時候,先檢查下導致堆積的原因,看符合上述的三個原因的哪一個。

  • 訊息生產(Producer)遠超預期
  • 訊息接收和持久化出現故障
  • 訊息消費(Consumer)能力下降致訊息堆積

找到原因之後,把問題處理完成,然後臨時擴容,來處理堆積的訊息資料。具體操作步驟如下,參考下面的圖:

  • 先分析原因,如果是Consumer或者Broker出現故障要先確保恢復故障;如果是訊息消費問題,先修復程式問題。
  • 暫停現有Consumer的消費動作。
  • 臨時建立好原先10倍(或者N倍)的queue數量,即新建topic,partition分割區是原來的10倍。
  • 寫一個程式,這個程式只做簡單的轉發工作,目的就是將消費積壓的訊息,均勻的消費到臨時擴容好的queue裡(這裡面有10倍的容量)。
  • Consumer也擴容10倍,對應一個Consumer消費一個臨時的Queue。相應的被消費者依賴的業務處理服務也需要對應的擴容,包含快取、資料庫、檔案服務等等。
  • 快速消費結束之後,記得恢復原來的消費架構,避免大量資源浪費。

總結

本文介紹了訊息堆積可能導致的原因,以及基本的處理步驟。大部分訊息中介軟體的健壯性都是非常好的。
業務的不合理使用和擴充套件一般是主要誘因,所以平時需要多關注業務服務的變化。