1. 程式人生 > 其它 >【RocketMQ】重試

【RocketMQ】重試

一. 訊息傳送重試

生產者在傳送訊息時,同步訊息失敗會重投,非同步訊息有重試,oneway沒有任何保證。訊息重投保證訊息儘可能傳送成功、不丟失,但可能會造成訊息重複傳送。訊息重複傳送在一般情況下不會發生,當出現訊息量大、網路抖動,就會大概率出現。另外,生產者主動重發、consumer負載變化也會導致重複訊息。如下方法可以設定訊息重試策略:

  • retryTimesWhenSendFailed: 同步傳送失敗重投次數,預設為2,因此生產者最多會嘗試傳送retryTimesWhenSendFailed + 1次。且生產者不會選擇上次失敗的broker,而是嘗試向其他broker傳送,最大程度保證訊息不丟。超過重投次數,丟擲異常,由客戶端保證訊息不丟。當出現RemotingException、MQClientException和部分MQBrokerException時會重投。
  • retryTimesWhenSendAsyncFailed: 非同步傳送失敗重試次數,非同步重試不會選擇其他broker,僅在同一個broker上做重試,不保證訊息不丟(導致broker掛掉後訊息一直無法傳送出去)。
  • retryAnotherBrokerWhenNotStoreOK: 訊息刷盤(主或備)超時或slave不可用(返回狀態非SEND_OK),是否嘗試傳送到其他broker,預設false。十分重要訊息可以開啟。

二. 訊息消費重試

Consumer消費訊息失敗後,要提供一種重試機制,令訊息再消費一次。Consumer消費訊息失敗通常可以認為有以下幾種情況:

  • 由於訊息本身的原因,例如反序列化失敗,訊息資料本身無法處理等。這種錯誤通常需要跳過這條訊息,再消費其它訊息,而這條失敗的訊息即使立刻重試消費,99%也不成功,所以最好提供一種定時重試機制,即過10秒後再重試。
  • 由於依賴的下游應用服務不可用,例如db連線不可用,外系統網路不可達等。遇到這種錯誤,即使跳過當前失敗的訊息,消費其他訊息同樣也會報錯。這種情況建議應用sleep 30s,再消費下一條訊息,這樣可以減輕Broker重試訊息的壓力

三. 重試佇列

  1. 考慮到異常恢復起來需要一些時間,會為重試佇列設定多個重試級別,每個重試級別都有與之相應的重投延時,重試次數越多投遞延時就越大。RocketMQ對於重試訊息的處理是先儲存至Topic名稱為“SCHEDULE_TOPIC_XXXX”的延遲佇列中,後臺定時任務按照對應的時間進行延時後重新投遞至"%RETRY%+consumerGroup"重試佇列中。
  1. RocketMQ會為每個消費組設定一個Topic名稱為"%RETRY%+consumerGroup"的重試佇列(這裡需要注意的是,這個Topic的重試佇列是針對消費者組的,而不是針對每個Topic設定的),用於暫時儲存因為各種異常而導致Consumer端無法消費的訊息
  1. 延時級別
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h