全部產品
Search
文件中心

ApsaraMQ for RocketMQ:訊息發送重試和流控機制

更新時間:Dec 11, 2024

本文為您介紹雲訊息佇列 RocketMQ 版的訊息發送重試機制和訊息流程控機制。

背景資訊

訊息發送重試

雲訊息佇列 RocketMQ 版的訊息發送重試機制主要為您解答如下問題:

  • 部分節點異常是否影響訊息發送?

  • 請求重試是否會阻塞業務調用?

  • 請求重試會帶來什麼不足?

訊息流程控

雲訊息佇列 RocketMQ 版的流控機制主要為您解答如下問題:

  • 系統在什麼情況下會觸發流控?

  • 觸發流控時用戶端行為是什嗎?

  • 應該如何避免觸發流控,以及如何應對突發流控?

訊息發送重試機制

重試基本概念

雲訊息佇列 RocketMQ 版用戶端串連服務端發起訊息發送請求時,可能會因為網路故障、服務異常等原因導致調用失敗。為保證訊息的可靠性,雲訊息佇列 RocketMQ 版在用戶端SDK中內建請求重試邏輯,嘗試通過重試發送達到最終調用成功的效果。

同步發送和非同步發送模式均支援訊息發送重試。

重試觸發條件

觸發訊息發送重試機制的條件如下:

  • 用戶端訊息發送請求調用失敗或請求逾時

    • 網路異常造成串連失敗或請求逾時。

    • 服務端節點處於重啟或下線等狀態造成串連失敗。

    • 服務端運行慢造成請求逾時。

  • 服務端返回失敗錯誤碼

    • 系統邏輯錯誤:因運行邏輯不正確造成的錯誤。

    • 系統流控錯誤:因容量超限造成的流控錯誤。

說明

對於事務訊息,只會進行透明重試(transparent retries),網路逾時或異常等情境不會進行重試。

重試流程

生產者在初始化時設定訊息發送最大重試次數,當出現上述觸發條件的情境時,生產者用戶端會按照設定的重試次數一直重試發送訊息,直到訊息發送成功或達到最大重試次數重試結束,並在最後一次重試失敗後返回調用錯誤響應。

  • 同步發送:調用線程會一直阻塞,直到某次重試成功或最終重試失敗,拋出錯誤碼和異常。

  • 非同步發送:調用線程不會阻塞,但調用結果會通過例外狀況事件或者成功事件返回。

稍候再試

  • 除服務端返回系統流控錯誤情境,其他觸發條件觸發重試後,均會立即進行重試,無等待間隔。

  • 若由於服務端返迴流控錯誤觸發重試,系統會按照指數退避策略進行延遲重試。

    指數退避演算法通過以下參數控制重試行為:

    • INITIAL_BACKOFF: 第一次失敗重試前後需等待多久,預設值:1秒。

    • MULTIPLIER :指數退避因子,即退避倍率,預設值:1.6。

    • JITTER :隨機抖動因子,預設值:0.2。

    • MAX_BACKOFF :等待間隔時間上限,預設值:120秒

    • MIN_CONNECT_TIMEOUT :最短稍候再試,預設值:20秒。

    建議演算法如下:

    ConnectWithBackoff()
      current_backoff = INITIAL_BACKOFF
      current_deadline = now() + INITIAL_BACKOFF
      while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT))!= SUCCESS)
        SleepUntil(current_deadline)
        current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF)
        current_deadline = now() + current_backoff + UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)

    更多資訊,請參見connection-backoff.md

功能約束

  • 鏈路耗時阻塞評估:從上述重試機制可以看出,在重試流程中生產者僅能控制最大重試次數。若由於系統異常觸發了SDK內建的重試邏輯,則服務端需要等待最終重試結果,可能會導致訊息發送請求鏈路被阻塞。對於某些即時調用類情境,您需要合理評估每次調用請求的逾時時間以及最大重試次數,避免影響全鏈路的耗時。

  • 最終異常兜底:雲訊息佇列 RocketMQ 版用戶端內建的發送請求重試機制並不能保證訊息發送一定成功。當最終重試仍然失敗時,業務方調用需要捕獲異常,並做好冗餘保護處理,避免訊息發送結果不一致。

  • 訊息重複問題:因遠程調用的不確定性,當雲訊息佇列 RocketMQ 版用戶端因請求逾時觸發訊息發送重試流程,此時用戶端無法感知服務端的處理結果,用戶端進行的訊息發送重試可能會產生訊息重複問題,商務邏輯需要自行處理訊息重複問題。

訊息流程控機制

訊息流程控基本概念

訊息流程控指的是系統容量或水位過高,雲訊息佇列 RocketMQ 版服務端會通過快速失敗返迴流控錯誤來避免底層資源承受過高壓力。

觸發條件

雲訊息佇列 RocketMQ 版的訊息流程控觸發條件如下:

  • 儲存壓力大:參考消費進度管理的原理機制,消費者分組的初始消費位點為當前隊列的最大消費位點。若某些情境例如業務上新等需要回溯到指定時刻前開始消費,此時隊列的儲存壓力會瞬間飆升,觸發訊息流程控。

  • 服務端請求任務排隊溢出:若消費者消費能力不足,導致隊列中有大量堆積訊息,當堆積訊息超過一定數量後會觸發訊息流程控,減少下遊消費系統壓力。

流控行為

當系統觸發訊息發送流控時,用戶端會收到系統限流錯誤和異常,錯誤碼資訊如下:

  • gRPC協議:

    • reply-code:530

    • reply-text關鍵詞:TOO_MANY_REQUESTS

    用戶端收到系統流控錯誤碼後,會根據指數退避策略進行訊息發送重試

  • Remoting協議:

    • reply-code:215

    • reply-text關鍵詞:message flow control

    商業版TCP協議Java SDK 1.9.0.Final以下版本限流時用戶端收到系統流控錯誤碼後,不會進行重試;商業版TCP協議Java SDK 1.9.0.Final及以上版本,用戶端收到系統流控錯誤碼後,會根據指數退避策略進行訊息發送重試

    開源版SDK發送限流時,用戶端收到系統流控錯誤碼後,不會進行重試;消費限流時會進行退避重試。

說明

gRPC協議和Remoting協議支援的用戶端版本詳情,請參見SDK相容性說明

處理建議

  • 如何避免觸發訊息流程控:觸發限流的根本原因是系統容量或水位過高,您可以利用可觀測性功能監控系統水位容量等,保證底層資源充足,避免觸發流控機制。

  • 突發訊息流程控處理:如果因為突發原因觸發訊息流程控,且用戶端內建的重試流程執行失敗,則建議業務方將請求調用臨時替換到其他系統進行應急處理。