最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Guava?Retryer實(shí)現(xiàn)接口重試的示例

 更新時(shí)間:2021年12月27日 09:55:26   作者:小黑說(shuō)Java  
本文主要介紹了Guava?Retryer實(shí)現(xiàn)接口重試的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

小黑在開(kāi)發(fā)中遇到個(gè)問(wèn)題,我負(fù)責(zé)的模塊需要調(diào)用某個(gè)三方服務(wù)接口查詢(xún)信息,查詢(xún)結(jié)果直接影響后續(xù)業(yè)務(wù)邏輯的處理;

這個(gè)接口偶爾會(huì)因網(wǎng)絡(luò)問(wèn)題出現(xiàn)超時(shí),導(dǎo)致我的業(yè)務(wù)邏輯無(wú)法繼續(xù)處理;

這個(gè)問(wèn)題該如何解決呢?,小黑首先想到的就是重試嘛,如果失敗了就再調(diào)用一次。

問(wèn)題來(lái)了,如果又失敗了呢?接著重試嘛。我們循環(huán)處理,比如循環(huán)5次,全失敗則任務(wù)服務(wù)不可用,結(jié)束調(diào)用。

如果我又想著5次調(diào)用間隔一段時(shí)間呢?第一次先隔1秒,然后3秒,然后5秒呢?

小黑發(fā)現(xiàn)事情沒(méi)那么簡(jiǎn)單,如果自己搞容易出BUG呀。

轉(zhuǎn)念一想,這個(gè)常見(jiàn)挺常見(jiàn),網(wǎng)上應(yīng)該有輪子呀,找找看。一不小心就讓我給找著啦,哈哈。

Guava Retryer

This is a small extension to Google's Guava library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that talks to a remote service with flaky uptime.

使用Guava Retryer你可以自定義來(lái)執(zhí)行重試,同時(shí)也可以監(jiān)控每次重試的結(jié)果和行為,最重要的基于 Guava 風(fēng)格的重試方式真的很方便。

引入依賴(lài)

<dependency>
      <groupId>com.github.rholder</groupId>
      <artifactId>guava-retrying</artifactId>
      <version>2.0.0</version>
</dependency>

快速開(kāi)始

Callable<Boolean> callable = new Callable<Boolean>() {
    public Boolean call() throws Exception {
        return true; // do something useful here
    }
};

Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
    .retryIfResult(Predicates.<Boolean>isNull()) // callable返回null時(shí)重試
    .retryIfExceptionOfType(IOException.class) // callable拋出IOException重試
    .retryIfRuntimeException() // callable拋出RuntimeException重試
    .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重試3次后停止
    .build();
try {
    retryer.call(callable);
} catch (RetryException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

在Callable的call()方法返回null,拋出IOException或者RuntimeException時(shí)會(huì)重試;
將在嘗試重試3次后停止,并拋出包含上次失敗嘗試信息的RetryException;
如果call()方法中彈出任何其他異常,它將被包裝并在ExecutionException中重新調(diào)用。

指數(shù)退避(Exponential Backoff)

根據(jù)wiki上對(duì)Exponential backoff的說(shuō)明,指數(shù)補(bǔ)償是一種通過(guò)反饋,成倍地降低某個(gè)過(guò)程的速率,以逐漸找到合適速率的算法。

在以太網(wǎng)中,該算法通常用于沖突后的調(diào)度重傳。根據(jù)時(shí)隙和重傳嘗試次數(shù)來(lái)決定延遲重傳。

在c次碰撞后(比如請(qǐng)求失?。瑫?huì)選擇0和2^c - 1之間的隨機(jī)值作為時(shí)隙的數(shù)量。

對(duì)于第1次碰撞來(lái)說(shuō),每個(gè)發(fā)送者將會(huì)等待0或1個(gè)時(shí)隙進(jìn)行發(fā)送。
而在第2次碰撞后,發(fā)送者將會(huì)等待0到3( 由2^2 -1 計(jì)算得到)個(gè)時(shí)隙進(jìn)行發(fā)送。
而在第3次碰撞后,發(fā)送者將會(huì)等待0到7( 由2^3 - 1 計(jì)算得到)個(gè)時(shí)隙進(jìn)行發(fā)送。
以此類(lèi)推……

Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
        .retryIfExceptionOfType(IOException.class)
        .retryIfRuntimeException()
        .withWaitStrategy(WaitStrategies.exponentialWait(100, 5, TimeUnit.MINUTES)) // 指數(shù)退避
        .withStopStrategy(StopStrategies.neverStop()) // 永遠(yuǎn)不停止重試
        .build();

創(chuàng)建一個(gè)永遠(yuǎn)重試的重試器,在每次重試失敗后以指數(shù)級(jí)退避間隔遞增,直到最多5分鐘。5分鐘后,從那時(shí)起每隔5分鐘重試一次。

斐波那契退避(Fibonacci Backoff)

斐波那契數(shù)列指的是這樣一個(gè)數(shù)列:

0,1,1,2,3,5,8,13,21,34,55,89...

這個(gè)數(shù)列從第3項(xiàng)開(kāi)始,每一項(xiàng)都等于前兩項(xiàng)之和。

Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
        .retryIfExceptionOfType(IOException.class)
        .retryIfRuntimeException()
        .withWaitStrategy(WaitStrategies.fibonacciWait(100, 2, TimeUnit.MINUTES)) // 斐波那契退避
        .withStopStrategy(StopStrategies.neverStop())
        .build();

創(chuàng)建一個(gè)永遠(yuǎn)重試的重試器,在每次重試失敗后以增加斐波那契退避間隔的方式等待,直到最多2分鐘。2分鐘后,從那時(shí)起每隔2分鐘重試一次。

與指數(shù)退避策略類(lèi)似,斐波那契退避策略遵循一種模式,即在每次嘗試失敗后等待的時(shí)間越來(lái)越長(zhǎng)。

對(duì)于這兩種策略的性能英國(guó)利茲大學(xué)專(zhuān)門(mén)做過(guò)性能測(cè)試,相比指數(shù)退避策略,斐波那契退避策略可能性能更好,吞吐量可能也更好。

重試監(jiān)聽(tīng)器

當(dāng)重試發(fā)生時(shí),如果需要額外做一些動(dòng)作,比如發(fā)送郵件通知之類(lèi)的,可以通過(guò)RetryListener,Guava Retryer在每次重試之后會(huì)自動(dòng)回調(diào)監(jiān)聽(tīng)器,并且支持注冊(cè)多個(gè)監(jiān)聽(tīng)。

@Slf4j
class DiyRetryListener<Boolean> implements RetryListener {
    @Override
    public <Boolean> void onRetry(Attempt<Boolean> attempt) {
        log.info("重試次數(shù):{}",attempt.getAttemptNumber());
        log.info("距離第一次重試的延遲:{}",attempt.getDelaySinceFirstAttempt());
        if(attempt.hasException()){
            log.error("異常原因:",attempt.getExceptionCause());
        }else {
            System.out.println("正常處理結(jié)果:{}" + attempt.getResult());
        }
    }
}

定義監(jiān)聽(tīng)器之后,需要在Retryer中進(jìn)行注冊(cè)。

        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                .retryIfResult(Predicates.<Boolean>isNull()) // callable返回null時(shí)重試
                .retryIfExceptionOfType(IOException.class) // callable拋出IOException重試
                .retryIfRuntimeException() // callable拋出RuntimeException重試
                .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重試3次后停止
                .withRetryListener(new DiyRetryListener<Boolean>()) // 注冊(cè)監(jiān)聽(tīng)器
                .build();

小結(jié)

Guava Retryer不光在重試策略上支持多種選擇,并且將業(yè)務(wù)邏輯的處理放在Callable中,和重試處理邏輯分開(kāi),實(shí)現(xiàn)了解耦,這比小黑自己去寫(xiě)循環(huán)處理要優(yōu)秀太多啦,Guava確實(shí)強(qiáng)大。

到此這篇關(guān)于Guava Retryer實(shí)現(xiàn)接口重試的示例的文章就介紹到這了,更多相關(guān)Guava Retryer 口重試 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合java診斷工具Arthas解讀

    SpringBoot整合java診斷工具Arthas解讀

    這篇文章主要介紹了SpringBoot整合java診斷工具Arthas,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring事務(wù)@Transactional注解四種不生效案例場(chǎng)景分析

    Spring事務(wù)@Transactional注解四種不生效案例場(chǎng)景分析

    這篇文章主要為大家介紹了Spring事務(wù)@Transactional注解四種不生效的案例場(chǎng)景示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • mybatis-spring:@MapperScan注解的使用

    mybatis-spring:@MapperScan注解的使用

    這篇文章主要介紹了mybatis-spring:@MapperScan注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java接口異步調(diào)用優(yōu)化技巧詳解

    Java接口異步調(diào)用優(yōu)化技巧詳解

    本文詳細(xì)介紹了在Java開(kāi)發(fā)中,如何通過(guò)異步調(diào)用等技巧來(lái)優(yōu)化接口的性能,有效避免阻塞和提高并發(fā)處理能力,提升系統(tǒng)的穩(wěn)定性和響應(yīng)速度
    2023-05-05
  • 通過(guò)一個(gè)map替換字符串中指定的字符變量方法

    通過(guò)一個(gè)map替換字符串中指定的字符變量方法

    下面小編就為大家?guī)?lái)一篇通過(guò)一個(gè)map替換字符串中指定的字符變量方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Mybatis resultType返回結(jié)果為null的問(wèn)題排查方式

    Mybatis resultType返回結(jié)果為null的問(wèn)題排查方式

    這篇文章主要介紹了Mybatis resultType返回結(jié)果為null的問(wèn)題排查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • MybatisPlus出現(xiàn)Error attempting to get column ‘xxx字段‘ from result set異常解決

    MybatisPlus出現(xiàn)Error attempting to get col

    本文重點(diǎn)分析使用@EnumValue注解轉(zhuǎn)換時(shí)遇到的一下錯(cuò)誤原因,及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • Spring代理對(duì)象導(dǎo)致的獲取不到原生對(duì)象注解的解決

    Spring代理對(duì)象導(dǎo)致的獲取不到原生對(duì)象注解的解決

    本文主要介紹了Spring代理對(duì)象導(dǎo)致的獲取不到原生對(duì)象注解的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Eclipse 安裝 SVN 在線(xiàn)插件教程

    Eclipse 安裝 SVN 在線(xiàn)插件教程

    這篇文章主要介紹了Eclipse 安裝 SVN 在線(xiàn)插件教程的相關(guān)資料,這里對(duì)安裝步驟進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下
    2016-11-11
  • Java使用BouncyCastle加密

    Java使用BouncyCastle加密

    本文主要介紹了Java使用BouncyCastle加密,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

简阳市| 卓尼县| 庆元县| 环江| 班玛县| 曲阳县| 高邑县| 康马县| 木兰县| 唐山市| 余干县| 瑞昌市| 高雄市| 万安县| 加查县| 泽州县| 九龙坡区| 庐江县| 呼图壁县| 武夷山市| 个旧市| 嵊泗县| 新丰县| 阳谷县| 罗平县| 庆阳市| 兴和县| 旬阳县| 阿图什市| 黑河市| 泗水县| 南漳县| 新津县| 望谟县| 蓬溪县| 霍山县| 城市| 城步| 饶阳县| 高阳县| 广饶县|