在接口調用中因爲各類緣由,可能會重置失敗的任務,使用Guava-Retrying能夠方便的實現重試功能。java
首先,須要引用Guava-Retrying的包git
<dependency>
<groupId>com.github.rholder</groupId>
<artifactId>guava-retrying</artifactId>
<version>2.0.0</version>
</dependency>
代碼示例:github
import com.github.rholder.retry.Retryer; import com.github.rholder.retry.RetryerBuilder; import com.github.rholder.retry.StopStrategies; import com.google.common.base.Predicates; import java.util.concurrent.TimeUnit; import static com.github.rholder.retry.WaitStrategies.incrementingWait; /** * @author wangxuexing * @descrption * @date */ public class RetryDemo { public static void main(String[] args) { Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder(). //若是異常會重試 retryIfException(). //若是結果爲false會重試 retryIfResult(Predicates.equalTo(false)). //重調策略 withWaitStrategy(incrementingWait(30, TimeUnit.SECONDS, 30, TimeUnit.SECONDS)). //嘗試次數 withStopStrategy(StopStrategies.stopAfterAttempt(3)). //註冊監聽 withRetryListener(new MyRetryListener()).build(); try { retryer.call(new TaskCallable()); } catch (Exception e) { e.printStackTrace(); } } }
其中TaskCallable是任務的具體實現類,它實現了Callable接口bash
import java.util.concurrent.Callable; /** * @author wangxuexing * @descrption * @date */ public class TaskCallable implements Callable<Boolean> { public Boolean call() throws Exception { return false; } }
另外,MyRetryListener監聽實現了RetryListener接口,每次重試都會回調註冊的監聽
import com.github.rholder.retry.Attempt; import com.github.rholder.retry.RetryListener; /** * @author wangxuexing * @descrption * @date */ public class MyRetryListener implements RetryListener { public <V> void onRetry(Attempt<V> attempt) { System.out.print("[retry]time=" + attempt.getAttemptNumber()); // 距離第一次重試的延遲 System.out.print(",delay=" + attempt.getDelaySinceFirstAttempt()); // 重試結果: 是異常終止, 仍是正常返回 System.out.print(",hasException=" + attempt.hasException()); System.out.print(",hasResult=" + attempt.hasResult()); // 是什麼緣由致使異常 if (attempt.hasException()) { System.out.print(",causeBy=" + attempt.getExceptionCause().toString()); } else {// 正常返回時的結果 System.out.print(",result=" + attempt.getResult()); } System.out.println(); } }
執行一下main方法,能夠看到執行的結果:dom
[retry]time=1,delay=0,hasException=false,hasResult=true,result=false [retry]time=2,delay=30000,hasException=false,hasResult=true,result=false [retry]time=3,delay=90000,hasException=false,hasResult=true,result=false com.github.rholder.retry.RetryException: Retrying failed to complete successfully after 3 attempts. at com.github.rholder.retry.Retryer.call(Retryer.java:174) at test.retryer.RetryDemo.main(RetryDemo.java:32)
下面詳細分析一下:ui
RetryerBuilder是一個factory建立者,能夠定製設置重試源且能夠支持多個重試源,能夠配置重試次數或重試超時時間,以及能夠配置等待時間間隔,建立重試者Retryer實例。google
RetryerBuilder的重試源支持Exception異常對象 和自定義斷言對象,經過retryIfException 和retryIfResult設置,同時支持多個且能兼容。
retryIfException,拋出runtime異常、checked異常時都會重試,可是拋出error不會重試。
retryIfRuntimeException只會在拋runtime異常的時候才重試,checked異常和error都不重試。
retryIfExceptionOfType容許咱們只在發生特定異常的時候才重試,好比NullPointerException和IllegalStateException都屬於runtime異常,也包括自定義的error
retryIfResult能夠指定你的Callable方法在返回值的時候進行重試spa
StopStrategy:中止重試策略,提供三種:
StopAfterDelayStrategy 設定一個最長容許的執行時間;好比設定最長執行10s,不管任務執行次數,只要重試的時候超出了最長時間,則任務終止,並返回重試異常RetryException。
NeverStopStrategy 不中止,用於須要一直輪訓知道返回指望結果的狀況。code
StopAfterAttemptStrategy 設定最大重試次數,若是超出最大重試次數則中止重試,並返回重試異常。對象
WaitStrategy:等待時長策略(控制時間間隔),返回結果爲下次執行時長:FixedWaitStrategy 固定等待時長策略。RandomWaitStrategy 隨機等待時長策略(能夠提供一個最小和最大時長,等待時長爲其區間隨機值)。IncrementingWaitStrategy 遞增等待時長策略(提供一個初始值和步長,等待時間隨重試次數增長而增長)。ExponentialWaitStrategy 指數等待時長策略。FibonacciWaitStrategy Fibonacci 等待時長策略。ExceptionWaitStrategy 異常時長等待策略。CompositeWaitStrategy 複合時長等待策略。