input!= null input instanceof Boolean ! Boolean .valueOf(( Boolean ) input)) // 返回值為false時(shí)重試 // 對應(yīng)Future獲取超時(shí)時(shí)間" />
0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Guava Retrying模塊使用場景

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-08 09:55 ? 次閱讀

在web應(yīng)用中,由于網(wǎng)絡(luò)原因或其他不可預(yù)測的原因,應(yīng)用間會出現(xiàn)調(diào)用失敗的情形,通過配置重試策略可以有效解決外在原因?qū)е碌南到y(tǒng)故障。

使用場景

  1. 微服務(wù)間各個(gè)服務(wù)模塊間的調(diào)用
  2. 第三方模塊遠(yuǎn)程交易調(diào)用
  3. 非業(yè)務(wù)異常導(dǎo)致可能失敗的情況

示例

構(gòu)建Retryer

private Retryer retryer = RetryerBuilder.newBuilder()
        .retryIfException() // 異常時(shí)重試
        .retryIfResult(input - > input!=null && input instanceof Boolean && !Boolean.valueOf((Boolean) input)) // 返回值為false時(shí)重試
        // 對應(yīng)Future獲取超時(shí)時(shí)間
        .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(4, TimeUnit.SECONDS,Executors.newFixedThreadPool(2))) //重試次數(shù)限制
        .withRetryListener(new RetryListener() { // 重試執(zhí)行邏輯
            @Override
            public < V > void onRetry(Attempt< V > attempt) {
                log.info("onRetry - > 重試次數(shù):{},距第一次重試時(shí)長:{}", attempt.getAttemptNumber(),attempt.getDelaySinceFirstAttempt());
                if(attempt.hasException()){ // 是否異常導(dǎo)致重試
                    Throwable exception = attempt.getExceptionCause(); // 執(zhí)行的異常
                    log.info("異常:{}", exception);
                }
                if(attempt.hasResult()){ // 是否有返回
                    V result = attempt.getResult();
                    log.info("返回:{}",result);
                }
            }
        })
        // 控制每次重試間隔時(shí)間,如果AttemptTimeLimiter設(shè)置多線程
        .withWaitStrategy(WaitStrategies.fixedWait(3,TimeUnit.SECONDS)) // 等待策略
        .withBlockStrategy(BlockStrategies.threadSleepStrategy()) // 阻塞策略
        //
        .withStopStrategy(StopStrategies.stopAfterAttempt(5)) // 停止策略
        .build();

使用Retryer讓業(yè)務(wù)代碼擁有重試能力

前兩次執(zhí)行時(shí)模擬返回false,則會執(zhí)行重試;當(dāng)?shù)?次時(shí),正常執(zhí)行業(yè)務(wù)代碼并返回true,結(jié)束重試

@Test
public void retryWhenResult() throws ExecutionException, RetryException {
   retryer.call(() - > {
       if(counter.incrementAndGet() == 3){// 模擬前2此返回false,觸發(fā)重試
           log.info(" 執(zhí)行業(yè)務(wù)代碼:{}次",counter.get());
           return true;
       }
       return false; 
   });
}

模擬前3次出現(xiàn)異常,則會執(zhí)行重試;當(dāng)?shù)?次時(shí),正常執(zhí)行業(yè)務(wù)代碼,結(jié)束重試

@Test
public void retryWhenException() throws ExecutionException, RetryException {
    retryer.call(() - > {
        if( counter.getAndIncrement() == 3 ){// 模擬前5此出現(xiàn)異常,觸發(fā)重試
            return counter;
        }
        log.info(" 執(zhí)行業(yè)務(wù)代碼: {}次", counter.get());
         throw new RuntimeException("ERROR"); 
    });
}

模擬前5此出現(xiàn)異常,由于Retryer配置重試次數(shù)為5,則最終業(yè)務(wù)代碼不會執(zhí)行

@Test
public void retryWhenResultOnFailure() throws ExecutionException, RetryException {
    retryer.call(() - > {
        if(counter.incrementAndGet() == 8){// 模擬前7此返回false,由于配置重試5次,因此最終失敗
            log.info(" 執(zhí)行業(yè)務(wù)代碼:{}次",counter.get());
            return true;
        }
        return false;
    });
}

執(zhí)行流程

圖片

執(zhí)行流程

通過RetryerBuilder構(gòu)建Retryer,調(diào)用Retryer#call,封裝業(yè)務(wù)代碼為其回調(diào)函數(shù)

  1. 開始循環(huán)執(zhí)行
  2. 由AttemptTimeLimiter#call執(zhí)行回調(diào)函數(shù)
  3. 將結(jié)果封裝為Attempt,包括兩種類型ResultAttempt,ExceptionAttempt。如果成功,記錄執(zhí)行結(jié)果、持續(xù)時(shí)長;如果失敗,記錄異常、持續(xù)時(shí)長
  4. 執(zhí)行監(jiān)聽RetyrListener#onRetry,可以配置多個(gè)監(jiān)聽
  5. 執(zhí)行拒絕斷言Predicate,根據(jù)返回值、執(zhí)行異常、返回異常類型判斷是否終止重試
  6. 如果滿足條件,則繼續(xù)重試;否則結(jié)束重試,并返回Attempt包含回調(diào)結(jié)果
  7. 根據(jù)終止策略StopStrategy判斷是否終止重試
  8. 根據(jù)等待策略WaitStrategy獲取等待時(shí)長
  9. 根據(jù)阻塞策略BlockStrategy與上一步等待時(shí)長阻塞重試,如果出現(xiàn)異常則拋出RetryException
  10. 重復(fù)執(zhí)行以上邏輯

配置

構(gòu)建Retryer主要通過RetryerBuilder.newBuilder()實(shí)現(xiàn),其相關(guān)配置如下:

配置策略名稱描述
AttemptTimeLimiters任務(wù)執(zhí)行時(shí)長限制
NoAttemptTimeLimit無時(shí)長限制
FixedAttemptTimeLimit固定時(shí)長限制
WaitStrategies重試等待策略
ExponentialWaitStrategy指數(shù)等待策略按指數(shù)增加重試間隔時(shí)長,比如第一次2^1100、2^2100、2^3*100...最多300000
FibonacciWaitStrategy斐波那契等待策略1100、1100、2100、3100、5*100...
FixedWaitStrategy固定時(shí)長等待策略按配置的固定間隔時(shí)間
RandomWaitStrategy隨機(jī)時(shí)長等待策略隨機(jī)間隔時(shí)間,可以設(shè)置隨機(jī)值范圍
IncrementingWaitStrategy遞增等待策略根據(jù)配置的初始值與增量進(jìn)行累加時(shí)間
ExceptionWaitStrategy異常等待策略根據(jù)異常類型指定等待時(shí)間
CompositeWaitStrategy復(fù)合等待策略可配置多個(gè)策略進(jìn)行組合
BlockStrategies阻塞策略根據(jù)WaitStrategies獲取阻塞時(shí)長
ThreadSleepStrategy線程等等策略通過Thread.sleet()實(shí)現(xiàn)
StopStrategies重試停止策略
NeverStopStrategy無限制策略
StopAfterAttemptStrategy限定次數(shù)策略
StopAfterDelayStrategy限定時(shí)長策略
NoAttemptTimeLimit限定次數(shù)

注意

  1. AttemptTimeLimiter中的FixedAttemptTimeLimit依賴于guava中的SimpleTimeLimiter,但是在guava高版本中該類已經(jīng)成了私有類

總結(jié)

Guava Retrying模塊能夠通過簡單的將代碼實(shí)現(xiàn)業(yè)務(wù)邏輯重試的功能,并且其配置中包含了重試的次數(shù)、時(shí)長控制、重試阻塞、終止策略等等, 在項(xiàng)目中是非常常用的一項(xiàng)技術(shù)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 模塊
    +關(guān)注

    關(guān)注

    7

    文章

    2655

    瀏覽量

    47293
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4284

    瀏覽量

    62325
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4723

    瀏覽量

    68236
收藏 人收藏

    評論

    相關(guān)推薦

    MOS管的應(yīng)用場景

    mos管的應(yīng)用場景,你了解么?低壓MOS管可稱為金屬氧化物半導(dǎo)體場效應(yīng)管,因?yàn)榈蛪篗OS管具有良好的開關(guān)特性,廣泛應(yīng)用在電子開關(guān)的電路中。如開關(guān)電源,電動(dòng)馬達(dá)、照明調(diào)光等!下面銀聯(lián)寶科技就跟大家一起
    發(fā)表于 11-14 09:24

    =>的使用場景有哪些

    使用場景
    發(fā)表于 10-27 13:25

    ARM的技術(shù)特征是什么?應(yīng)用場景有哪些?

    ARM的技術(shù)特征是什么?應(yīng)用場景有哪些?
    發(fā)表于 11-05 07:32

    藍(lán)牙模塊的5大應(yīng)用場景

    打印機(jī)打印出符合要求的二維碼以二維碼的形式將藍(lán)牙MAC地址打印出來,方便藍(lán)牙產(chǎn)品對藍(lán)牙MAC地址進(jìn)行讀取,能夠有效提高工作效率。五、智能門鎖在智能門鎖的應(yīng)用場景中,利用藍(lán)牙技術(shù)可以滿足不同用戶和權(quán)限
    發(fā)表于 12-09 09:37

    MS9331的應(yīng)用場景是什么?

    MS9331的應(yīng)用場景是什么?
    發(fā)表于 02-11 06:41

    labview 和 wincc 的區(qū)別 使用場景

    labview 和 wincc 的區(qū)別 使用場景 都是上位機(jī)軟件,都可以做監(jiān)控軟件 wincc的名氣也比較大 對比的資料較少 寫這些文章的人,從自己的從事的行業(yè)出發(fā),帶有自己的思維 使用的場景 肯定
    發(fā)表于 10-27 18:01

    一文深度了解串口WiFi模塊作用,串口WiFi模塊的應(yīng)用場景

    串口WiFi模塊作用,串口WiFi模塊的應(yīng)用場景
    發(fā)表于 03-01 14:25 ?28次下載

    無線模塊的十大應(yīng)用場景

    無線模塊的十大應(yīng)用場景
    發(fā)表于 05-08 10:17 ?18次下載

    網(wǎng)絡(luò)音頻模塊有哪些應(yīng)用場景?

    對音頻信號進(jìn)行編解碼、處理和轉(zhuǎn)換,支持多種音頻格式和協(xié)議,例如MP3、AAC、G.711等。網(wǎng)絡(luò)音頻模塊可以實(shí)現(xiàn)單向或雙向的語音通信,也可以實(shí)現(xiàn)多路的語音廣播。 網(wǎng)絡(luò)音頻模塊有哪些應(yīng)用場景? 網(wǎng)絡(luò)音頻
    的頭像 發(fā)表于 05-16 10:24 ?638次閱讀
    網(wǎng)絡(luò)音頻<b class='flag-5'>模塊</b>有哪些應(yīng)<b class='flag-5'>用場景</b>?

    LoRa模塊的應(yīng)用場景

    LoRa遠(yuǎn)程無線傳輸技術(shù)擁有傳輸距離遠(yuǎn)、功耗低、性能高、無線組網(wǎng),遠(yuǎn)程定位等一系列特點(diǎn),使用終端與LoRa基站組件低功耗數(shù)據(jù)傳輸網(wǎng)絡(luò)成為了物聯(lián)網(wǎng)大規(guī)模推廣應(yīng)用的理想選擇之一。那么LoRa模塊可以使用在哪些應(yīng)用場景呢?思為無線就來為您解答。
    的頭像 發(fā)表于 04-18 15:10 ?835次閱讀
    LoRa<b class='flag-5'>模塊</b>的應(yīng)<b class='flag-5'>用場景</b>

    DC電源模塊不同的尺寸可以適應(yīng)實(shí)際應(yīng)用場景

    DC電源模塊是現(xiàn)代電子設(shè)備的必備部件之一,其可提供穩(wěn)定的直流電源,保證電子設(shè)備正常運(yùn)行。DC電源模塊尺寸的選擇直接影響到其適應(yīng)的應(yīng)用場景及其性能表現(xiàn)。本文將從尺寸方面分析DC電源模塊
    的頭像 發(fā)表于 08-29 10:32 ?523次閱讀

    Guava Collect常見的集合類

    Guava工具包中的一個(gè)子模塊,主要對jdk中的集合操作添加了一些簡易的API,同時(shí)也是對Collections工具類的擴(kuò)展。當(dāng)然Guava還定義了一些特定場景的數(shù)據(jù)結(jié)構(gòu)以及一些針對
    的頭像 發(fā)表于 10-08 11:35 ?432次閱讀

    千兆光模塊和萬兆光模塊的適用場景有哪些

    隨著網(wǎng)絡(luò)技術(shù)的不斷進(jìn)步,千兆光模塊和萬兆光模塊成為使用最為廣泛的兩款光模塊。本文將介紹一些光模塊使用場景,以便用戶更加深入的了解這兩款光
    的頭像 發(fā)表于 10-16 12:06 ?820次閱讀

    DC電源模塊和AC電源模塊都有各自的優(yōu)點(diǎn)和適用場景

    BOSHIDA DC電源模塊和AC電源模塊都有各自的優(yōu)點(diǎn)和適用場景 DC電源模塊和AC電源模塊都有各自的優(yōu)點(diǎn)和適
    的頭像 發(fā)表于 12-29 14:39 ?867次閱讀
    DC電源<b class='flag-5'>模塊</b>和AC電源<b class='flag-5'>模塊</b>都有各自的優(yōu)點(diǎn)和適<b class='flag-5'>用場景</b>

    800G光模塊的應(yīng)用場景

    隨著科技發(fā)展,數(shù)據(jù)中心對光模塊需求大增。800G光模塊作為一種高速光傳輸技術(shù),應(yīng)用場景擴(kuò)展并引起廣泛關(guān)注。主要應(yīng)用于數(shù)據(jù)中心、云計(jì)算和網(wǎng)絡(luò)通信等領(lǐng)域,滿足現(xiàn)代社會對高帶寬、快速數(shù)據(jù)傳輸?shù)男枨蟆?/div>
    的頭像 發(fā)表于 03-11 15:30 ?580次閱讀