跳至主要內容
版本:5.0

傳送重試和限制策略

本主題說明 Apache RocketMQ 的訊息傳送重試機制和限制機制。

背景

訊息傳送重試

Apache RocketMQ 的傳送重試機制回答以下問題

  • 如果某些節點有故障,是否可以傳送訊息?

  • 重試要求是否會封鎖呼叫執行緒?

  • 傳送重試有哪些缺點?

限制

Apache RocketMQ 的限制機制回答以下問題

  • 在什麼情況下會觸發限制?

  • 觸發限制時,用戶端行為為何?

  • 如何避免觸發限制,以及如何處理意外限制?

訊息傳送重試

傳送重試簡介

當 Apache RocketMQ 的生產者用戶端呼叫代理伺服器傳送訊息時,呼叫可能會因網路故障或服務例外等原因而失敗。為了確保訊息可靠性,Apache RocketMQ 在用戶端 SDK 中提供內建邏輯,在要求成功之前重試失敗的要求。

同步和非同步傳送模式都支援訊息傳送重試。

觸發條件

傳送重試可以由下列條件之一觸發

  • 用戶端呼叫失敗或要求逾時。

    • 網路例外導致連線失敗或要求逾時。

    • 連線關閉,因為代理伺服器節點已關閉或正在重新啟動。

    • 要求逾時,因為代理伺服器執行緩慢。

  • 代理伺服器傳回錯誤碼。

    • 邏輯錯誤:由不正確的執行邏輯所導致的錯誤。

    • 節流:由過多流量觸發的節流。

注意

對於交易訊息,只會執行 透明重試。在網路例外或逾時情境中不會執行重試。

重試程序

您可以在生產者初始化訊息時指定生產者的最大重試次數。當發生上述觸發條件之一時,生產者用戶端會嘗試再次傳送訊息,直到訊息傳送成功或達到最大重試次數。如果最後一次重試仍失敗,則會傳回呼叫錯誤。

  • 同步傳送:呼叫執行緒會封鎖,直到重試成功或最後一次重試失敗。如果最後一次重試失敗,系統會傳回錯誤碼和例外。

  • 非同步傳送:呼叫執行緒不會封鎖。呼叫結果會以例外事件或成功事件傳回。

重試間隔

  • 訊息在失敗時會立即重試,除非重試是由節流觸發。

  • 如果重試是由節流觸發,訊息會在指數後退協定的指定間隔重試。指數後退演算法使用下列參數來控制重試行為

    • 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 的內建重試邏輯,代理程式必須等到最後的重試結果,而傳送請求連結會被封鎖。因此,您必須評估每個呼叫的逾時持續時間和最大重試次數,以防止重試封鎖連結。

  • 最後例外處理:Apache RocketMQ 客户端的內建傳送重試機制無法確保失敗訊息已成功傳送。如果最後一次重試仍然失敗,呼叫者必須捕捉例外並提供備援保護,以防止訊息傳送結果不一致。

  • 重複訊息:當 Apache RocketMQ 生產者客户端重新傳送訊息時,客户端不知道代理程式上假設失敗訊息的處理結果。因此,代理程式上可能存在重複訊息。請確定您的業務邏輯可以妥善處理此類情況。

節流

節流簡介

當系統容量使用量超過閾值時,Apache RocketMQ 代理程式會拒絕請求並傳回錯誤,以避免過度負擔底層資源。

觸發條件

Apache RocketMQ 的節流機制會由下列其中一個條件觸發

  • 高儲存壓力:如 消費者進度管理 的工作機制區段所述,消費者群組會從佇列的最大偏移量開始使用訊息。如果要求消費者群組從較早的時間點開始使用,佇列上的儲存壓力會激增並觸發節流。這會發生在回溯情境中,例如推出新業務。

  • 代理伺服器上過多未使用的訊息:如果使用者無法以訊息傳送給他們的相同速率使用訊息,要求會堆積在佇列中。如果堆積的訊息數量超過閾值,將會觸發節流以減輕下游系統的負擔。

行為

當觸發節流時,生產者用戶端會收到下列錯誤訊息和例外狀況

  • reply-code:530

  • reply-text:TOO_MANY_REQUESTS

收到這些訊息時,用戶端會根據指數後退協定重試訊息。如需更多資訊,請參閱訊息傳送重試

建議

建議

  • 如何避免觸發節流:使用可觀察的指標來監控系統容量,並適當地調整基礎資源。

  • 如何處理節流:如果觸發節流,且用戶端中的內建重試程序失敗,您可以暫時將呼叫切換到另一個系統。