傳送重試和限制策略
本主題說明 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
收到這些訊息時,用戶端會根據指數後退協定重試訊息。如需更多資訊,請參閱訊息傳送重試。
建議
建議
如何避免觸發節流:使用可觀察的指標來監控系統容量,並適當地調整基礎資源。
如何處理節流:如果觸發節流,且用戶端中的內建重試程序失敗,您可以暫時將呼叫切換到另一個系統。