精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何在RocketMQ中合理使用重試機制構建彈性高可用系統

OSC開源社區 ? 來源:OSC開源社區 ? 作者:OSC開源社區 ? 2022-11-23 10:18 ? 次閱讀

		

引言

本文主要介紹在使用 RocketMQ 時為什么需要重試與兜底機制,生產者與消費者觸發重試的條件和具體行為,如何在 RocketMQ 中合理使用重試機制,幫助構建彈性,高可用系統的最佳實踐。

RocketMQ 的重試機制包括三部分,分別是生產者重試,服務端內部數據復制遇到非預期問題時重試,消費者消費重試。本文中僅討論生產者重試和消費者消費重試兩種面向用戶側的實現。


		

生產者發送重試

Cloud Native

RocketMQ 的生產者在發送消息到服務端時,可能會因為網絡問題,服務異常等原因導致調用失敗,這時候應該怎么辦?如何盡可能的保證消息不丟失呢?

1. 生產者重試次數

RocketMQ 在客戶端中內置了請求重試邏輯,支持在初始化時配置消息發送最大重試次數(默認為 2 次),失敗時會按照設置的重試次數重新發送。直到消息發送成功,或者達到最大重試次數時結束,并在最后一次失敗后返回調用錯誤的響應。對于同步發送和異步發送,均支持消息發送重試。

同步發送:調用線程會一直阻塞,直到某次重試成功或最終重試失?。ǚ祷劐e誤碼或拋出異常)。

異步發送:調用線程不會阻塞,但調用結果會通過回調的形式,以異常事件或者成功事件返回。

2. 生產者重試間隔

在介紹生產者重試前,我們先來了解下流控的概念,流控一般是指服務端壓力過大,容量不足時服務端會限制客戶端收發消息的行為,是服務端自我保護的一種設計。RocketMQ 會根據當前是否觸發了流控而采用不同的重試策略:

非流控錯誤場景:其他觸發條件觸發重試后,均會立即進行重試,無等待間隔。流控錯誤場景:系統會按照預設的指數退避策略進行延遲重試。

為什么要引入退避和隨機抖動?

如果故障是由過載流控引起的,重試會增加服務端負載,導致情況進一步惡化,因此客戶端在遇到流控時會在兩次嘗試之間等待一段時間。每次嘗試后的等待時間都呈指數級延長。指數回退可能導致很長的回退時間,因為指數函數增長很快。指數退避算法通過以下參數控制重試行為,更多信息,請參見 connection-backoff.md。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)

特別說明:對于事務消息,只會進行透明重試(transparent retries),網絡超時或異常等場景不會進行重試。

3. 重試帶來的副作用

不停的重試看起來很美好,但也是有副作用的,主要包括兩方面:消息重復,服務端壓力增大

遠程調用的不確定性,因請求超時觸發消息發送重試流程,此時客戶端無法感知服務端的處理結果;客戶端進行的消息發送重試可能會導致消費方重復消費,應該按照用戶ID、業務主鍵等信息冪等處理消息。

較多的重試次數也會增大服務端的處理壓力。

4. 用戶的最佳實踐是什么

1)合理設置發送超時時間,發送的最大次數

發送的最大次數在初始化客戶端時配置在 ClientConfiguration;對于某些實時調用類場景,可能會導致消息發送請求鏈路被阻塞導致業務請求整體耗時高或耗時;需要合理評估每次調用請求的超時時間以及最大重試次數,避免影響全鏈路的耗時。2)如何保證發送消息不丟失由于分布式環境的復雜性,例如網絡不可達時 RocketMQ 客戶端發送請求重試機制并不能保證消息發送一定成功。業務方需要捕獲異常,并做好冗余保護處理,常見的解決方案有兩種:

向調用方返回業務處理失敗;

嘗試將失敗的消息存儲到數據庫,然后由后臺線程定時重試,保證業務邏輯的最終一致性。

3)關注流控異常導致無法重試觸發流控的根本原因是系統容量不足,如果因為突發原因觸發消息流控,且客戶端內置的重試流程執行失敗,

則建議執行服務端擴容,將請求調用臨時替換到其他系統進行應急處理。4)早期版本客戶端如何使用故障延遲機制進行發送重試?對于 RocketMQ 4.x 和 3.x 以下客戶端開啟故障延遲機制可以用:

producer.setSendLatencyFaultEnable(true)

配置重試次數使用:

producer.setRetryTimesWhenSendFailed()producer.setRetryTimesWhenSendAsyncFailed()

消費者消費重試

Cloud Native

消息中間件做異步解耦時的一個典型問題是如果下游服務處理消息事件失敗,那應該怎么做呢?RocketMQ 的消息確認機制以及消費重試策略可以幫助分析如下問題:

如何保證業務完整處理消息?

消費重試策略可以在設計實現消費者邏輯時保證每條消息處理的完整性,避免部分消息消費異常導致業務狀態不一致。

業務應用異常時處理中的消息狀態如何恢復?

當系統出現異常(宕機故障)等場景時,處理中的消息狀態如何恢復,消費重試具體行為是什么。

1. 什么是消費重試?

什么時候認為消費失敗?

消費者在接收到消息后將調用用戶的消費函數執行業務邏輯。如果客戶端返回消費失敗 ReconsumeLater,拋出非預期異常,或消息處理超時(包括在 PushConsumer 中排隊超時),只要服務端服務端一定時間內沒收到響應,將認為消費失敗。

消費重試是什么?

消費者在消費某條消息失敗后,服務端會根據重試策略重新向客戶端投遞該消息。超過一次定數后若還未消費成功,則該消息將不再繼續重試,直接被發送到死信隊列中;

重試過程狀態機:消息在重試流程中的狀態和變化邏輯;

重試間隔:上一次消費失敗或超時后,下次重新嘗試消費的間隔時間;

最大重試次數:消息可被重試消費的最大次數。

2. 消息重試的場景

需要注意重試是應對異常情況,給予程序再次消費失敗消息的機會,不應該被用作常態化的鏈路。

推薦使用場景:

業務處理失敗,失敗原因跟當前的消息內容相關,預期一段時間后可執行成功;

是一個小概率事件,對于大批的消息只有很少量的失敗,后面的消息大概率會消費成功,是非常態化的。

正例:消費邏輯是扣減庫存,極少量商品因為樂觀鎖版本沖突導致扣減失敗,重試一般立刻成功。錯誤使用場景:

消費處理邏輯中使用消費失敗來做條件判斷的結果分流,是不合理的。

反例:訂單在數據庫中狀態已經是已取消,此時如果收到發貨的消息,處理時不應返回消費失敗,而應該返回成功并標記不用發貨。

消費處理中使用消費失敗來做處理速率限流,是不合理的。

限流的目的是將超出流量的消息暫時堆積在隊列中達到削峰的作用,而不是讓消息進入重試鏈路。

這種做法會讓消息反復在服務端和客戶端之間傳遞,增大了系統的開銷,主要包括以下方面:

RocketMQ 內部重試涉及寫放大,每一次重試將生成新的重試消息,大量重試將帶來嚴重的 IO 壓力;

重試有復雜的退避邏輯,內部實現為梯度定時器,該定時器本身不具備高吞吐的特性,大量重試將導致重試消息無法及時出隊。重試的間隔將不穩定,將導致大量重試消息延后消費,即削峰的周期被大幅度延長。

3. 不要以重試替代限流

上述誤用的場景實際上是組合了限流和重試能力來進行削峰,RocketMQ 推薦的削峰最佳手段為組合限流和堆積,業務以保護自身為前提,需要對消費流量進行限流,并利用 RocketMQ 提供的堆積能力將超出業務當前處理的消息滯后消費,以達到削峰的目的。下圖中超過處理能力的消息都應該被堆積在服務端,而不是通過消費失敗進行重試。


		

如果不想依賴額外的產品/組件來完成該功能,也可以利用一些本地工具類,比如 Guava 的 RateLimiter 來完成單機限流。如下所示,聲明一個 50 QPS 的 RateLimiter,在消費前以阻塞的方式 acquire 一個令牌,獲取到即處理消息,未獲取到阻塞。

RateLimiter rateLimiter = RateLimiter.create(50); PushConsumer pushConsumer = provider.newPushConsumerBuilder() .setClientConfiguration(clientConfiguration) // 設置訂閱組名稱 .setConsumerGroup(consumerGroup) // 設置訂閱的過濾器 .setSubscriptionExpressions(Collections.singletonMap(topic, filterExpression)) .setMessageListener(messageView -> { // 阻塞直到獲得一個令牌,也可以配置一個超時時間 rateLimiter.acquire(); LOGGER.info("Consume message={}", messageView); return ConsumeResult.SUCCESS; }) .build();

4. PushConsumer 消費重試策略

PushConsumer 消費消息時,消息的幾個主要狀態如下:

Ready:已就緒狀態。消息在消息隊列RocketMQ版服務端已就緒,可以被消費者消費;

Inflight:處理中狀態。消息被消費者客戶端獲取,處于消費中還未返回消費結果的狀態;

Commit:提交狀態。消費成功的狀態,消費者返回成功響應即可結束消息的狀態機;

DLQ:死信狀態

消費邏輯的最終兜底機制,若消息一直處理失敗并不斷進行重試,直到超過最大重試次數還未成功,此時消息不會再重試。

該消息會被投遞至死信隊列。您可以通過消費死信隊列的消息進行業務恢復。

最大重試次數

PushConsumer 的最大重試次數由創建時決定。例如,最大重試次數為 3 次,則該消息最多可被投遞 4 次,1 次為原始消息,3 次為重試投遞次數。

重試間隔時間

無序消息(非順序消息):重試間隔為階梯時間,具體時間如下:

說明:若重試次數超過 16 次,后面每次重試間隔都為 2 小時。

順序消息:重試間隔為固定時間,默認為 3 秒。

5. SimpleConsumer 消費重試策略

和 PushConsumer 消費重試策略不同,SimpleConsumer 消費者的重試間隔是預分配的,每次獲取消息消費者會在調用 API 時設置一個不可見時間參數 InvisibleDuration,即消息的最大處理時長。若消息消費失敗觸發重試,不需要設置下一次重試的時間間隔,直接復用不可見時間參數的取值。

由于不可見時間為預分配的,可能和實際業務中的消息處理時間差別較大,可以通過 API 接口修改不可見時間。例如,預設消息處理耗時最多 20 ms,但實際業務中 20 ms內消息處理不完,可以修改消息不可見時間,延長消息處理時間,避免消息觸發重試機制。修改消息不可見時間需要滿足以下條件:

消息處理未超時

消息處理未提交消費狀態

如下圖所示,消息不可見時間修改后立即生效,即從調用 API 時刻開始,重新計算消息不可見時間。

最大重試次數

與 PushConsumer 相同。

消息重試間隔

消息重試間隔 = 不可見時間 - 消息實際處理時長例如:消息不可見時間為 30 ms,實際消息處理用了 10 ms 就返回失敗響應,則距下次消息重試還需要 20 ms,此時的消息重試間隔即為 20 ms;若直到 30 ms 消息還未處理完成且未返回結果,則消息超時,立即重試,此時重試間隔即為 0 ms。SimpleConsumer 的消費重試間隔通過消息的不可見時間控制。


	
//消費示例:使用SimpleConsumer消費普通消息,主動獲取消息處理并提交。
ClientServiceProvider provider1 = ClientServiceProvider.loadService();
String topic1 = "Your Topic";
FilterExpression filterExpression1 = new FilterExpression("Your Filter Tag", FilterExpressionType.TAG);


SimpleConsumer simpleConsumer = provider1.newSimpleConsumerBuilder()
        //設置消費者分組。
        .setConsumerGroup("Your ConsumerGroup")
        //設置接入點。
        .setClientConfiguration(ClientConfiguration.newBuilder().setEndpoints("Your Endpoint").build())
        //設置預綁定的訂閱關系。
        .setSubscriptionExpressions(Collections.singletonMap(topic, filterExpression))
        .build();
List messageViewList = null;
try {
    //SimpleConsumer需要主動獲取消息,并處理。
    messageViewList = simpleConsumer.receive(10, Duration.ofSeconds(30));
    messageViewList.forEach(messageView -> {
        System.out.println(messageView);
        //消費處理完成后,需要主動調用ACK提交消費結果。
        //沒有ack會被認為消費失敗
        try {
            simpleConsumer.ack(messageView);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    });
} catch (ClientException e) {
    //如果遇到系統流控等原因造成拉取失敗,需要重新發起獲取消息請求。
    e.printStackTrace();
}
修改消息的不可見時間

案例:某產品使用消息隊列來發送解耦“視頻渲染”的業務邏輯,發送方發送任務編號,消費方收到編號后處理任務。由于消費方的業務邏輯耗時較長,消費者重新消費到同一個任務時,該任務未完成,只能返回消費失敗。在這種全新的 API 下,用戶可以調用可以通過修改不可見時間給消息續期,實現對單條消息狀態的精確控制。

simpleConsumer.changeInvisibleDuration();

simpleConsumer.changeInvisibleDurationAsync();

6. 功能約束與最佳實踐

設置消費的最大超時時間和次數

盡快明確的向服務端返回成功或失敗,不要以超時(有時是異常拋出)代替消費失敗。

不要用重試機制來進行業務限流

錯誤示例:如果當前消費速度過高觸發限流,則返回消費失敗,等待下次重新消費。正確示例:如果當前消費速度過高觸發限流,則延遲獲取消息,稍后再消費。

發送重試和消費重試會導致相同的消息重復消費,消費方應該有一個良好的冪等設計

正確示例:某系統中消費的邏輯是為某個用戶發送短信,該短信已經發送成功了,當消費者應用重復收到該消息,此時應該返回消費成功。

總結

Cloud Native

本文主要介紹重試的基本概念,生產者消費者收發消息時觸發重試的條件和具體行為,以及 RocketMQ 收發容錯的最佳實踐。重試策略幫助我們從隨機的、短暫的瞬態故障中恢復,是在容忍錯誤時,提高可用性的一種強大機制。但請謹記 “重試是對于分布式系統來說自私的”,因為客戶端認為其請求很重要,并要求服務端花費更多資源來處理,盲目的重試設計不可取,合理的使用重試可以幫助我們構建更加彈性且可靠的系統。

審核編輯:郭婷


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 線程
    +關注

    關注

    0

    文章

    504

    瀏覽量

    19651

原文標題:RocketMQ重試機制詳解及最佳實踐

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    彈性云服務器怎么樣?好用嗎?

    答案是肯定的。彈性云服務器以其彈性伸縮、可用性、靈活性、高性能以及安全防護等特性,為用戶提供了高效、可靠、靈活的計算服務。無論是初創企業還是大型企業,都能從中受益。用戶可以輕松部署和
    的頭像 發表于 10-15 16:15 ?107次閱讀

    使用bq769x0對可用系統進行故障監控

    電子發燒友網站提供《使用bq769x0對可用系統進行故障監控.pdf》資料免費下載
    發表于 10-15 10:13 ?0次下載
    使用bq769x0對<b class='flag-5'>高</b><b class='flag-5'>可用</b>性<b class='flag-5'>系統</b>進行故障監控

    系統鬧脾氣:用「因果推斷」哄穩技術的心

    。 ? ? 舉個例子:服務雪崩 A服務調用B服務之間發生了雪崩效應,原本B本身有點小問題,而A由于內置的各種容錯和重試機制,反而加劇了B的服務負載,導致其出現更多的失敗。這些失敗觸發了A的無限重試,使得情況進一步惡化,最終引
    的頭像 發表于 08-14 10:42 ?234次閱讀
    當<b class='flag-5'>系統</b>鬧脾氣:用「因果推斷」哄穩技術的心

    并發系統的藝術:如何在流量洪峰中游刃有余

    前言 我們常說的三,并發、可用、高性能,這些技術是構建現代互聯網應用程序所必需的。對于京東618備戰來說,所有的
    的頭像 發表于 08-05 13:43 ?233次閱讀
    <b class='flag-5'>高</b>并發<b class='flag-5'>系統</b>的藝術:如<b class='flag-5'>何在</b>流量洪峰中游刃有余

    何在RK3562J的AMP雙系統實現裸核中斷嵌套機制

    3. 中斷嵌套機制 中斷嵌套是一種有效的中斷處理機制,它允許系統根據中斷的優先級來響應和處理中斷,從而確保關鍵任務能夠及時得到處理,具有實時性、靈活性好、響應快速等特點,但傳統
    發表于 07-29 16:29

    何在不同應用場景下構建音頻測試環境

    在之前的文章,我們已經詳細介紹了基礎音頻參數和AP525的軟硬件配置。本文將延續這一主題,以泰凌TLSR9518A EVB作為測試設備(DUT),向大家展示如何在不同應用場景下構建音頻測試環境。
    的頭像 發表于 07-03 15:00 ?457次閱讀
    如<b class='flag-5'>何在</b>不同應用場景下<b class='flag-5'>構建</b>音頻測試環境

    華為云 FunctionGraph 構建可用系統的實踐

    ,詳細介紹如何構建可用的 Serverless 計算平臺,實現客戶和平臺雙贏。 可用介紹
    的頭像 發表于 05-09 23:14 ?430次閱讀
    華為云 FunctionGraph <b class='flag-5'>構建</b><b class='flag-5'>高</b><b class='flag-5'>可用</b><b class='flag-5'>系統</b>的實踐

    半導體芯片封裝推拉力測試機合理選擇需要考慮哪些方面?

    選擇半導體芯片封裝推拉力測試機時,可以考慮以下幾個方面:1.功能-首先要考慮測試機的功能,特別是是否有半導體芯片封裝推拉力測試的功能。此外,還可以選擇具有多功能全自動切換模組的測試機,以便進行多種
    的頭像 發表于 03-12 17:41 ?671次閱讀
    半導體芯片封裝推拉力測<b class='flag-5'>試機</b><b class='flag-5'>合理</b>選擇需要考慮哪些方面?

    深度解析RocketMQ的消息存儲整體架構

    在Client和Server之間完成一次消息發送時,需要對發送的消息進行一個協議約定,因此就有必要自定義RocketMQ的消息協議。同時,為了高效地在網絡傳輸消息和對收到的消息讀取,就需要對消息進行編解碼。
    的頭像 發表于 02-01 11:36 ?2107次閱讀
    深度解析<b class='flag-5'>RocketMQ</b>的消息存儲整體架構

    RocketMQ各類重復消費的原理淺析

    隨著大數據和云計算時代的到來,我國的各個產業每天都在產生不可估計的數據,以及對數據的各式各樣的需求,消息中間件在處理數據、消費數據的過程中越來越受到重視。在并發、微服務、分布式的場景下,如何合理
    的頭像 發表于 01-08 09:29 ?1069次閱讀
    <b class='flag-5'>RocketMQ</b><b class='flag-5'>中</b>各類重復消費的原理淺析

    RocketMQ協議是什么?RocketMQ協議特點

    分布式消息系統中生產者和消費者之間的高效可靠通信。它支持同步和異步消息傳遞模式,可以實現靈活和響應迅速的通信方式。 RocketMQ協議基于發布-訂閱消息模式,生產者將消息發布到特定的主題,消費者訂閱這些主題以接收消息。該協議通過實現消息持久化、消息確認
    的頭像 發表于 01-03 16:11 ?781次閱讀

    記錄RocketMQ在centos7上的安裝過程

    本文記錄RocketMQ在centos7上的安裝過程,沒有技術的探討,僅僅是安裝記錄,以作備忘。
    的頭像 發表于 01-02 11:41 ?1442次閱讀
    記錄<b class='flag-5'>RocketMQ</b>在centos7上的安裝過程

    薄膜鍵盤彈性可用彈 UV 膠

    鍵盤彈性體高彈UV膠,用于薄膜鍵盤的彈性體部分。
    的頭像 發表于 12-30 09:22 ?490次閱讀
    薄膜鍵盤<b class='flag-5'>彈性</b>體<b class='flag-5'>可用</b>的<b class='flag-5'>高</b>彈 UV 膠

    磁盤RocketMQ構建的索引結構

    RocketMQ 廣泛使用于各類業務場景,在實際生產場景,用戶通常會選擇消息 ID 或者特定的業務 Key(例如學號,訂單號)來查詢和定位特定的一批消息,進而定位分布式系統
    的頭像 發表于 12-22 10:43 ?378次閱讀
    磁盤<b class='flag-5'>中</b><b class='flag-5'>RocketMQ</b><b class='flag-5'>構建</b>的索引結構

    小三軸荷重試驗機是什么?有哪些介紹

    小三軸荷重試驗機是什么?有哪些介紹
    的頭像 發表于 12-07 09:09 ?433次閱讀
    小三軸荷<b class='flag-5'>重試</b>驗機是什么?有哪些介紹