Apache Camel中的短重试与长重试
《駱駝設(shè)計(jì)模式》一書介紹了20種模式以及用于設(shè)計(jì)基于Apache Camel的集成解決方案的眾多技巧和最佳實(shí)踐。 每個(gè)模式都基于真實(shí)的用例,并提供了Camel特定的實(shí)現(xiàn)細(xì)節(jié)和最佳實(shí)踐。 為了讓您有這本書的感覺,以下是該書的重試模式摘錄,其中介紹了如何在Apache Camel中進(jìn)行短期和長(zhǎng)期退休。
上下文和問題
從本質(zhì)上講,集成應(yīng)用程序必須通過網(wǎng)絡(luò)與其他系統(tǒng)進(jìn)行交互。 隨著基于動(dòng)態(tài)云的環(huán)境成為規(guī)范,并且微服務(wù)體系結(jié)構(gòu)將應(yīng)用程序劃分為更細(xì)粒度的服務(wù),成功的服務(wù)通信已成為許多分布式應(yīng)用程序的基本前提。 與其他服務(wù)進(jìn)行通信的服務(wù)必須能夠透明地處理下游系統(tǒng)中可能發(fā)生的瞬態(tài)故障,并繼續(xù)運(yùn)行而不會(huì)造成任何中斷。 由于可以將瞬態(tài)故障視為基礎(chǔ)結(jié)構(gòu)級(jí)別的故障,網(wǎng)絡(luò)連接的丟失,繁忙服務(wù)所施加的超時(shí)和限制等。這些情況很少發(fā)生,并且通常會(huì)自行糾正,并且通常可以重試操作成功。
力量與解決方案
再現(xiàn)和解釋瞬態(tài)故障可能是一項(xiàng)艱巨的任務(wù),因?yàn)檫@些故障可能是由不定期發(fā)生且與外部系統(tǒng)相關(guān)的多種因素造成的。 諸如Chaos Monkey之類的工具可用于模擬不可預(yù)測(cè)的系統(tǒng)中斷,并在需要時(shí)讓您測(cè)試應(yīng)用程序的彈性。 處理瞬態(tài)故障的一個(gè)好策略是重試該操作,并希望它能夠成功(如果錯(cuò)誤確實(shí)是瞬態(tài)的,它將成功;只要保持鎮(zhèn)靜并繼續(xù)重試)。
要實(shí)現(xiàn)“重試”邏輯,需要考慮以下幾個(gè)方面:
重試哪些失敗?
某些服務(wù)操作(例如HTTP調(diào)用和關(guān)系數(shù)據(jù)庫交互)是重試邏輯的潛在候選者,但是在實(shí)現(xiàn)它之前需要進(jìn)一步分析。 關(guān)系數(shù)據(jù)庫可能會(huì)因?yàn)橄拗剖褂眠^多資源而拒絕連接嘗試,或者由于并發(fā)修改而拒絕SQL插入操作。 在這些情況下重試可能會(huì)成功。 但是,如果關(guān)系數(shù)據(jù)庫由于憑據(jù)錯(cuò)誤而拒絕連接,或者由于外鍵約束SQL插入操作失敗,則重試該操作將無濟(jì)于事。 與HTTP調(diào)用類似,重試連接超時(shí)或響應(yīng)超時(shí)可能會(huì)有所幫助,但是重試由業(yè)務(wù)錯(cuò)誤引起的SOAP Fault毫無意義。 因此,請(qǐng)謹(jǐn)慎選擇重試次數(shù)。
多久重試一次?
一旦確定了重試的必要性,就應(yīng)該調(diào)整特定的重試策略以滿足兩個(gè)應(yīng)用程序的性質(zhì):具有重試邏輯的服務(wù)使用者和具有短暫故障的服務(wù)提供者。 例如,如果實(shí)時(shí)集成服務(wù)無法處理請(qǐng)求,則可能只允許它在返回響應(yīng)之前進(jìn)行幾次重試,且延遲很短,而基于批處理的異步服務(wù)可能能夠承擔(dān)更多的重試操作。更長(zhǎng)的延遲和指數(shù)回退。 重試策略還應(yīng)考慮其他因素,例如服務(wù)消耗合同和服務(wù)提供商的SLA。 例如,非常激進(jìn)的重試策略可能會(huì)導(dǎo)致服務(wù)使用者進(jìn)一步受到限制,甚至被列入黑名單,或者它可能會(huì)使服務(wù)完全過載并降級(jí),從而使服務(wù)完全無法恢復(fù)。 有些API可能會(huì)指示您一段時(shí)間內(nèi)的剩余請(qǐng)求計(jì)數(shù),并將響應(yīng)中的信息列入黑名單,但有些API可能不會(huì)。 因此,重試策略定義了多久重試一次,以及多長(zhǎng)時(shí)間之后您才能接受它是非暫時(shí)性故障并放棄的事實(shí)。
冪等
重試操作時(shí),請(qǐng)考慮對(duì)該操作可能產(chǎn)生的副作用。 重試邏輯將消耗的服務(wù)操作應(yīng)設(shè)計(jì)為冪等的。 使用相同的數(shù)據(jù)輸入重試相同的操作應(yīng)該沒有任何副作用。 想象一個(gè)請(qǐng)求已成功處理,但響應(yīng)尚未返回。 服務(wù)使用者可以假設(shè)請(qǐng)求失敗,然后重試相同的操作,這可能會(huì)產(chǎn)生一些意外的副作用。
監(jiān)控方式
跟蹤和報(bào)告重試也很重要。 如果某些操作在成功之前不斷被重試,或者在失敗之前被重試了太多次,則必須識(shí)別并修復(fù)這些操作。 由于在沒有適當(dāng)監(jiān)視的情況下,服務(wù)中的重試應(yīng)該對(duì)服務(wù)使用者透明,因此它們可能未被檢測(cè)到,并以負(fù)面的方式影響了整個(gè)系統(tǒng)的穩(wěn)定性和性能。
超時(shí)和SLA
當(dāng)下游系統(tǒng)發(fā)生暫時(shí)性故障并且重試邏輯生效時(shí),重試服務(wù)的總處理時(shí)間將大大增加。 與其從重試和延遲次數(shù)的角度考慮重試參數(shù),重要的是從服務(wù)SLA和服務(wù)使用者超時(shí)的角度來驅(qū)動(dòng)這些值。 因此,請(qǐng)考慮處理請(qǐng)求所允許的最大時(shí)間,并確定可以擠入該時(shí)間范圍的最大重試次數(shù)和延遲時(shí)間(包括處理時(shí)間)。
機(jī)械學(xué)
使用Camel和ActiveMQ有幾種不同的重試方法。
駱駝重新交付政策(重試)
這是在駱駝中進(jìn)行重試的最流行和通用的方法。 重新交付策略定義了重試規(guī)則(例如重試和延遲的次數(shù),是否使用沖突避免和指數(shù)退避乘數(shù)以及日志記錄),然后可以將其應(yīng)用于處理流程的多個(gè)errorHandler和onException塊。 每當(dāng)引發(fā)異常時(shí),將應(yīng)用重新交付策略中的規(guī)則。
駱駝重新交付政策示例
重試機(jī)制的主要區(qū)別在于Camel錯(cuò)誤處理邏輯不會(huì)重試整個(gè)路由,而是僅重試處理流程中的失敗端點(diǎn)。 這要?dú)w功于在駱駝路線中連接端點(diǎn)的通道。 每當(dāng)處理節(jié)點(diǎn)拋出異常時(shí),該異常就會(huì)傳播回并被通道捕獲,然后可以應(yīng)用各種錯(cuò)誤處理策略。 此處的另一個(gè)重要區(qū)別是基于Camel的錯(cuò)誤處理和重新傳遞邏輯是內(nèi)存中的,并且它在重試期間會(huì)阻塞線程,從而產(chǎn)生后果。 如果所有線程都被阻塞并等待重試,則可能會(huì)用完線程。 線程的所有者可以是使用者,也可以是帶有來自路由的線程池的某種并行處理結(jié)構(gòu)(例如并行拆分器,收件人列表或線程DSL)。 例如,如果我們有一個(gè)帶有十個(gè)請(qǐng)求處理線程的HTTP使用者,一個(gè)繁忙且拒絕連接的數(shù)據(jù)庫以及一個(gè)具有指數(shù)退避的RedeliveryPolicy,則在十個(gè)請(qǐng)求之后,所有線程將最終等待重試,而沒有線程將可用于處理新請(qǐng)求。 解決此線程阻塞問題的方法是選擇
asyncDelayedRedelivery,其中Camel將使用線程池并異步安排重新交付。 但是線程池將重新交付請(qǐng)求存儲(chǔ)在內(nèi)部隊(duì)列中,因此此選項(xiàng)可以很快消耗所有堆。 還請(qǐng)記住,所有錯(cuò)誤處理程序都有一個(gè)線程池,而一個(gè)
CamelContext,因此,除非您為持久的重新交付配置了特定的線程池,否則該池可能會(huì)在一條路徑中耗盡,而在另一條路徑中阻塞線程。 另一個(gè)含義是,由于重試邏輯在內(nèi)存中的性質(zhì),重新啟動(dòng)應(yīng)用程序?qū)G失重試狀態(tài),并且將無法分發(fā)或保持該狀態(tài)。
總體而言,這種Camel重試機(jī)制非常適合短時(shí)本地重試,并且可以克服網(wǎng)絡(luò)故障或資源短暫鎖定的情況。 對(duì)于更長(zhǎng)的延遲,最好使用具有群集性和非線程阻塞性的持久交付來重新設(shè)計(jì)應(yīng)用程序(下面將介紹這種解決方案)。
ActiveMQ經(jīng)紀(jì)人重新交付(長(zhǎng)期重試)
該重試機(jī)制與前兩個(gè)機(jī)制具有不同的特征,因?yàn)樗怯纱肀旧?#xff08;而不是消息使用者或駱駝路由引擎)管理的。 ActiveMQ借助其調(diào)度程序,可以延遲傳遞消息。 此功能是代理重新交付插件的基礎(chǔ)。 重新交付插件可以攔截死信處理并重新安排失敗消息以重新交付。 計(jì)劃將失敗的消息傳遞到原始隊(duì)列的尾部,然后重新傳遞給消息使用者,而不是傳遞給DLQ。 當(dāng)總消息順序并不重要,并且消費(fèi)者之間的吞吐量和負(fù)載分配很重要時(shí),這很有用。
ActiveMQ重新交付示例
旁注–我知道,無恥的插件,但是我對(duì)這本書的研究感到非常興奮。 您可以在這里享受40%的折扣,直到6月底為止! 希望你喜歡。 與以前的方法的不同之處在于,該消息在代理消息存儲(chǔ)中是持久的,并且在代理或駱駝路由重新啟動(dòng)后仍會(huì)繼續(xù)存在而不會(huì)影響重新交付的時(shí)間。 另一個(gè)優(yōu)點(diǎn)是,每個(gè)重試消息都沒有線程被阻塞。 由于消息已返回給代理,因此可以使用競(jìng)爭(zhēng)消費(fèi)者模式將消息傳遞給其他消費(fèi)者。 但是副作用是消息順序丟失了,因?yàn)橄⒈环胖迷谙㈥?duì)列的尾部。 同樣,使用調(diào)度程序運(yùn)行代理也會(huì)對(duì)性能產(chǎn)生一些影響。 這種重試機(jī)制對(duì)于長(zhǎng)時(shí)間的重試很有用,因?yàn)槟鸁o法承受每個(gè)失敗消息的阻塞線程。 當(dāng)您希望保留消息并對(duì)其進(jìn)行聚類以進(jìn)行重新交付時(shí),它也很有用。
請(qǐng)注意,與使用代理重新交付插件相比,手動(dòng)實(shí)現(xiàn)代理重新交付邏輯很容易。 您所要做的就是捕獲異常并發(fā)送帶有
AMQ_SCHEDULED_DELAY標(biāo)頭指向中間隊(duì)列。 一旦延遲過去,該消息將被使用,并且將重試相同的操作。 您可以多次重新計(jì)劃和處理同一條消息,直到放棄并將消息放入退避或死信隊(duì)列中。
翻譯自: https://www.javacodegeeks.com/2017/06/short-retry-vs-long-retry-apache-camel-2.html
總結(jié)
以上是生活随笔為你收集整理的Apache Camel中的短重试与长重试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国大陆市场电竞显示器 2023 年 8
- 下一篇: maven 父maven_Maven的春