最近項目中用到了很多 RPC 調(diào)用岳锁,其中定義了一個如下的重試策略:
public static final RetryStrategy<Object> DEFAULT_RETRY_STRATEGY =
new ExponentialBackoffAndJitterBuilder()
.retryOn(Calls.getCommonRecoverableThrowables())
.retryOn(RetryableSBAAGTSvcException.class)
.withInitialIntervalMillis(RETRY_INITIAL_INTERVAL_MILLIS)
.withMaxAttempts(RETRY_MAX_ATTEMPTS)
.build();
關(guān)于 指數(shù)退避抖動 算法 Exponential Backoff And Jitter绩衷,參考如下兩篇文章:
指數(shù)退避的原理是對于連續(xù)錯誤響應(yīng),重試等待間隔越來越長。
您應(yīng)該實施最長延遲間隔和最大重試次數(shù)咳燕。最長延遲間隔和最大重試次數(shù)不一定是固定值勿决,并且應(yīng)當(dāng)根據(jù)正在執(zhí)行的操作和其他本地因素(例如網(wǎng)絡(luò)延遲)進行設(shè)置。
大多數(shù)指數(shù)退避算法會利用抖動(隨機延遲)來防止連續(xù)的沖突招盲。
由于在這些情況下您并未嘗試避免此類沖突低缩,因此無需使用此隨機數(shù)字。但是曹货,如果使用并發(fā)客戶端咆繁,抖動可幫助您更快地成功執(zhí)行請求。
以下代碼演示如何在 Java 中實施此增量延遲顶籽。
public class RetryDemo {
// 最長延遲間隔玩般,單位是毫秒
private static int MAX_WAIT_INTERVAL = 100000;
// 最大重試次數(shù)
private static int MAX_RETRIES = 5;
public enum Results {
SUCCESS,
NOT_READY,
THROTTLED,
SERVER_ERROR
}
public static void main(String[] args) {
doOperationAndWaitForResult();
}
// 指數(shù)退避 算法
public static void doOperationAndWaitForResult() {
try {
int retries = 0;
boolean retry = false;
do {
long waitTime = Math.min(getWaitTimeExp(retries), MAX_WAIT_INTERVAL);
System.out.print("等待時間:" + waitTime + " ms \n");
// Wait for the result.
Thread.sleep(waitTime);
// Get the result of the asynchronous operation.
Results result = getAsyncOperationResult();
if (Results.SUCCESS == result) {
retry = false;
} else if (Results.NOT_READY == result) {
retry = true;
} else if (Results.THROTTLED == result) {
retry = true;
} else if (Results.SERVER_ERROR == result) {
retry = true;
}
else {
retry = false;
}
} while (retry && (retries++ < MAX_RETRIES));
}
catch (Exception ex) {
}
}
// 假設(shè)每次都返回 SERVER_ERROR
public static Results getAsyncOperationResult() {
return Results.SERVER_ERROR;
}
// 根據(jù)重試的次數(shù),返回 2 的指數(shù)的等待時間礼饱,單位是毫秒
public static long getWaitTimeExp(int retryCount) {
long waitTime = ((long) Math.pow(2, retryCount) * 100L);
return waitTime;
}
}
輸出如下:
等待時間:100 ms
等待時間:200 ms
等待時間:400 ms
等待時間:800 ms
等待時間:1600 ms
等待時間:3200 ms