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

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

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

前言

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

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

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

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

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

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

轉(zhuǎn)念一想,這個常見挺常見,網(wǎ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你可以自定義來執(zhí)行重試,同時也可以監(jiān)控每次重試的結(jié)果和行為,最重要的基于 Guava 風格的重試方式真的很方便。

引入依賴

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

快速開始

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時重試
    .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時會重試;
將在嘗試重試3次后停止,并拋出包含上次失敗嘗試信息的RetryException;
如果call()方法中彈出任何其他異常,它將被包裝并在ExecutionException中重新調(diào)用。

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

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

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

在c次碰撞后(比如請求失敗),會選擇0和2^c - 1之間的隨機值作為時隙的數(shù)量。

對于第1次碰撞來說,每個發(fā)送者將會等待0或1個時隙進行發(fā)送。
而在第2次碰撞后,發(fā)送者將會等待0到3( 由2^2 -1 計算得到)個時隙進行發(fā)送。
而在第3次碰撞后,發(fā)送者將會等待0到7( 由2^3 - 1 計算得到)個時隙進行發(fā)送。
以此類推……

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

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

斐波那契退避(Fibonacci Backoff)

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

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

這個數(shù)列從第3項開始,每一項都等于前兩項之和。

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

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

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

對于這兩種策略的性能英國利茲大學專門做過性能測試,相比指數(shù)退避策略,斐波那契退避策略可能性能更好,吞吐量可能也更好。

重試監(jiān)聽器

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

@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)聽器之后,需要在Retryer中進行注冊。

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

小結(jié)

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

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

相關(guān)文章

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

    SpringBoot整合java診斷工具Arthas解讀

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

    Spring事務@Transactional注解四種不生效案例場景分析

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

    mybatis-spring:@MapperScan注解的使用

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

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

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

    通過一個map替換字符串中指定的字符變量方法

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

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

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

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

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

    Spring代理對象導致的獲取不到原生對象注解的解決

    本文主要介紹了Spring代理對象導致的獲取不到原生對象注解的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • Eclipse 安裝 SVN 在線插件教程

    Eclipse 安裝 SVN 在線插件教程

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

    Java使用BouncyCastle加密

    本文主要介紹了Java使用BouncyCastle加密,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06

最新評論

墨竹工卡县| 察雅县| 洛宁县| 安泽县| 长沙县| 隆德县| 富川| 鸡泽县| 香河县| 武川县| 灌阳县| 三门县| 通道| 肥东县| 甘孜县| 林西县| 同江市| 勐海县| 丹寨县| 拜城县| 苗栗市| 衡东县| 濮阳市| 兰坪| 宁陵县| 光山县| 临泉县| 浦城县| 通榆县| 凤山市| 信宜市| 东乌珠穆沁旗| 余干县| 余干县| 文水县| 通海县| 且末县| 临清市| 金华市| 武功县| 隆子县|