日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

这或许是实现重试最优雅的姿势了!

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这或许是实现重试最优雅的姿势了! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用場景

在日常開發中,我們經常會遇到需要調用外部服務和接口的場景。外部服務對于調用者來說一般都是不可靠的,尤其是在網絡環境比較差的情況下,網絡抖動很容易導致請求超時等異常情況,這時候就需要使用失敗重試策略重新調用 API 接口來獲取。重試策略在服務治理方面也有很廣泛的使用,通過定時檢測,來查看服務是否存活(Active)。

Guava Retrying 是一個靈活方便的重試組件,包含了多種的重試策略,而且擴展起來非常容易。

用作者的話來說:

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-retrying 你可以自定義來執行重試,同時也可以監控每次重試的結果和行為,最重要的基于 Guava 風格的重試方式真的很方便。

代碼示例

以下會簡單列出 guava-retrying 的使用方式:

  • 如果拋出 IOException 則重試,如果返回結果為 null 或者等于 2 則重試,固定等待時長為 300 ms,最多嘗試 3 次;

Callable<Integer> task = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return2;} };Retryer<Integer> retryer = RetryerBuilder.<Integer>newBuilder().retryIfResult(Predicates.<Integer>isNull()).retryIfResult(Predicates.equalTo(2)).retryIfExceptionOfType(IOException.class).withStopStrategy(StopStrategies.stopAfterAttempt(3)).withWaitStrategy(WaitStrategies.fixedWait(300, TimeUnit.MILLISECONDS)).build(); try {retryer.call(task); } catch (ExecutionException e) {e.printStackTrace(); } catch (RetryException e) {e.printStackTrace(); }
  • 出現異常則執行重試,每次任務執行最長執行時間限定為 3 s,重試間隔時間初始為 3 s,最多重試 1 分鐘,隨著重試次數的增加每次遞增 1 s,每次重試失敗,打印日志;

@Overridepublic Integer call() throws Exception {return2;} };Retryer<Integer> retryer = RetryerBuilder.<Integer>newBuilder().retryIfException().withStopStrategy(StopStrategies.stopAfterDelay(30,TimeUnit.SECONDS)).withWaitStrategy(WaitStrategies.incrementingWait(3, TimeUnit.SECONDS,1,TimeUnit.SECONDS)).withAttemptTimeLimiter(AttemptTimeLimiters.<Integer>fixedTimeLimit(3,TimeUnit.SECONDS)).withRetryListener(new RetryListener() {@Overridepublic <V> void onRetry(Attempt<V> attempt) {if (attempt.hasException()){attempt.getExceptionCause().printStackTrace();}}}).build(); try {retryer.call(task); } catch (ExecutionException e) {e.printStackTrace(); } catch (RetryException e) {e.printStackTrace(); }

核心執行邏輯

long startTime = System.nanoTime(); for (int attemptNumber = 1; ; attemptNumber++) {Attempt<V> attempt;try {// 執行成功V result = attemptTimeLimiter.call(callable);attempt = new ResultAttempt<V>(result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));} catch (Throwable t) {// 執行失敗attempt = new ExceptionAttempt<V>(t, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));}// 監聽器處理for (RetryListener listener : listeners) {listener.onRetry(attempt);}// 是否符合終止策略if (!rejectionPredicate.apply(attempt)) {return attempt.get();}// 是否符合停止策略if (stopStrategy.shouldStop(attempt)) {thrownew RetryException(attemptNumber, attempt);} else {// 計算下次重試間隔時間long sleepTime = waitStrategy.computeSleepTime(attempt);try {blockStrategy.block(sleepTime);} catch (InterruptedException e) {Thread.currentThread().interrupt();thrownew RetryException(attemptNumber, attempt);}} }

依賴引入

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

默認的guava中也有包含。

主要接口介紹

  • Attempt:一次執行任務;

  • AttemptTimeLimiter:單次任務執行時間限制(如果單次任務執行超時,則終止執行當前任務);

  • BlockStrategies:任務阻塞策略(通俗的講就是當前任務執行完,下次任務還沒開始這段時間做什么……),默認策略為:BlockStrategies.THREAD_SLEEP_STRATEGY 也就是調用 Thread.sleep(sleepTime);

  • RetryException:重試異常;

  • RetryListener:自定義重試監聽器,可以用于異步記錄錯誤日志;

  • StopStrategy:停止重試策略,提供三種:

    • StopAfterDelayStrategy :設定一個最長允許的執行時間;比如設定最長執行10s,無論任務執行次數,只要重試的時候超出了最長時間,則任務終止,并返回重試異常RetryException;

    • NeverStopStrategy :不停止,用于需要一直輪訓知道返回期望結果的情況;

    • StopAfterAttemptStrategy :設定最大重試次數,如果超出最大重試次數則停止重試,并返回重試異常;

  • WaitStrategy:等待時長策略(控制時間間隔),返回結果為下次執行時長:

    • FixedWaitStrategy:固定等待時長策略;

    • RandomWaitStrategy:隨機等待時長策略(可以提供一個最小和最大時長,等待時長為其區間隨機值)

    • IncrementingWaitStrategy:遞增等待時長策略(提供一個初始值和步長,等待時間隨重試次數增加而增加)

    • ExponentialWaitStrategy:指數等待時長策略;

    • FibonacciWaitStrategy :Fibonacci 等待時長策略;

    • ExceptionWaitStrategy :異常時長等待策略;

    • CompositeWaitStrategy :復合時長等待策略;

總結

以上是生活随笔為你收集整理的这或许是实现重试最优雅的姿势了!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。