Java基于Guava Retrying實(shí)現(xiàn)重試功能
在接口調(diào)用中由于各種原因,可能會(huì)重置失敗的任務(wù),使用Guava-Retrying可以方便的實(shí)現(xiàn)重試功能。
首先,需要引用Guava-Retrying的包
<dependency> <groupId>com.github.rholder</groupId> <artifactId>guava-retrying</artifactId> <version>2.0.0</version> </dependency>
代碼示例:
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().
//如果異常會(huì)重試
retryIfException().
//如果結(jié)果為false會(huì)重試
retryIfResult(Predicates.equalTo(false)).
//重調(diào)策略
withWaitStrategy(incrementingWait(30, TimeUnit.SECONDS, 30, TimeUnit.SECONDS)).
//嘗試次數(shù)
withStopStrategy(StopStrategies.stopAfterAttempt(3)).
//注冊監(jiān)聽
withRetryListener(new MyRetryListener()).build();
try {
retryer.call(new TaskCallable());
} catch (Exception e) {
e.printStackTrace();
}
}
}
其中TaskCallable是任務(wù)的具體實(shí)現(xiàn)類,它實(shí)現(xiàn)了Callable接口
import java.util.concurrent.Callable;
/**
* @author wangxuexing
* @descrption
* @date
*/
public class TaskCallable implements Callable<Boolean> {
public Boolean call() throws Exception {
return false;
}
}
另外,MyRetryListener監(jiān)聽實(shí)現(xiàn)了RetryListener接口,每次重試都會(huì)回調(diào)注冊的監(jiān)聽
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());
// 重試結(jié)果: 是異常終止, 還是正常返回
System.out.print(",hasException=" + attempt.hasException());
System.out.print(",hasResult=" + attempt.hasResult());
// 是什么原因?qū)е庐惓?
if (attempt.hasException()) {
System.out.print(",causeBy=" + attempt.getExceptionCause().toString());
} else {// 正常返回時(shí)的結(jié)果
System.out.print(",result=" + attempt.getResult());
}
System.out.println();
}
}
執(zhí)行一下main方法,可以看到執(zhí)行的結(jié)果:
[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)
下面詳細(xì)分析一下:
RetryerBuilder是一個(gè)factory創(chuàng)建者,可以定制設(shè)置重試源且可以支持多個(gè)重試源,可以配置重試次數(shù)或重試超時(shí)時(shí)間,以及可以配置等待時(shí)間間隔,創(chuàng)建重試者Retryer實(shí)例。
- RetryerBuilder的重試源支持Exception異常對(duì)象 和自定義斷言對(duì)象,通過retryIfException 和retryIfResult設(shè)置,同時(shí)支持多個(gè)且能兼容。
- retryIfException,拋出runtime異常、checked異常時(shí)都會(huì)重試,但是拋出error不會(huì)重試。
- retryIfRuntimeException只會(huì)在拋runtime異常的時(shí)候才重試,checked異常和error都不重試。
- retryIfExceptionOfType允許我們只在發(fā)生特定異常的時(shí)候才重試,比如NullPointerException和IllegalStateException都屬于runtime異常,也包括自定義的error
- retryIfResult可以指定你的Callable方法在返回值的時(shí)候進(jìn)行重試
StopStrategy:停止重試策略,提供三種:
StopAfterDelayStrategy 設(shè)定一個(gè)最長允許的執(zhí)行時(shí)間;比如設(shè)定最長執(zhí)行10s,無論任務(wù)執(zhí)行次數(shù),只要重試的時(shí)候超出了最長時(shí)間,則任務(wù)終止,并返回重試異常RetryException。
NeverStopStrategy 不停止,用于需要一直輪訓(xùn)知道返回期望結(jié)果的情況。
StopAfterAttemptStrategy 設(shè)定最大重試次數(shù),如果超出最大重試次數(shù)則停止重試,并返回重試異常。
- WaitStrategy:等待時(shí)長策略(控制時(shí)間間隔),返回結(jié)果為下次執(zhí)行時(shí)長:
- FixedWaitStrategy 固定等待時(shí)長策略。
- RandomWaitStrategy 隨機(jī)等待時(shí)長策略(可以提供一個(gè)最小和最大時(shí)長,等待時(shí)長為其區(qū)間隨機(jī)值)。
- IncrementingWaitStrategy 遞增等待時(shí)長策略(提供一個(gè)初始值和步長,等待時(shí)間隨重試次數(shù)增加而增加)。
- ExponentialWaitStrategy 指數(shù)等待時(shí)長策略。
- FibonacciWaitStrategy Fibonacci 等待時(shí)長策略。
- ExceptionWaitStrategy 異常時(shí)長等待策略。
- CompositeWaitStrategy 復(fù)合時(shí)長等待策略。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)短信驗(yàn)證碼的示例代碼
Java是一種流行的編程語言,驗(yàn)證碼是一種常用的網(wǎng)絡(luò)安全技術(shù)。Java發(fā)展至今,網(wǎng)上也出現(xiàn)了各種各樣的驗(yàn)證碼,下面是用Java實(shí)現(xiàn)短信驗(yàn)證碼的總結(jié),感興趣的可以了解一下2023-03-03
SpringCache常用注解及key中參數(shù)值為null問題解析
這篇文章主要介紹了SpringCache常用注解及key中參數(shù)值為null的問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
Java switch case數(shù)據(jù)類型原理解析
這篇文章主要介紹了Java switch case數(shù)據(jù)類型原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
MyBatis?多表聯(lián)合查詢及優(yōu)化方法
大家都知道Hibernate 是全自動(dòng)的數(shù)據(jù)庫持久層框架,它可以通過實(shí)體來映射數(shù)據(jù)庫,通過設(shè)置一對(duì)多、多對(duì)一、一對(duì)一、多對(duì)多的關(guān)聯(lián)來實(shí)現(xiàn)聯(lián)合查詢,接下來通過本文給大家介紹MyBatis?多表聯(lián)合查詢及優(yōu)化,需要的朋友可以參考下2022-08-08
springboot2中session超時(shí),退到登錄頁面方式
這篇文章主要介紹了springboot2中session超時(shí),退到登錄頁面方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java MD5消息摘要算法原理及實(shí)現(xiàn)代碼
這篇文章主要介紹了Java MD5消息摘要算法原理及實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09

