自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

網(wǎng)絡(luò)又超時(shí)了......怎么辦?

開(kāi)發(fā) 前端
Guava Retrying模塊能夠通過(guò)簡(jiǎn)單的將代碼實(shí)現(xiàn)業(yè)務(wù)邏輯重試的功能,并且其配置中包含了重試的次數(shù)、時(shí)長(zhǎng)控制、重試阻塞、終止策略等等, 在項(xiàng)目中是非常常用的一項(xiàng)技術(shù)。

在web應(yīng)用中,由于網(wǎng)絡(luò)原因或其他不可預(yù)測(cè)的原因,應(yīng)用間會(huì)出現(xiàn)調(diào)用失敗的情形,通過(guò)配置重試策略可以有效解決外在原因?qū)е碌南到y(tǒng)故障。

使用場(chǎng)景

  • 微服務(wù)間各個(gè)服務(wù)模塊間的調(diào)用。
  • 第三方模塊遠(yuǎn)程交易調(diào)用。
  • 非業(yè)務(wù)異常導(dǎo)致可能失敗的情況。

示例

構(gòu)建Retryer

private Retryer retryer = RetryerBuilder.newBuilder()
.retryIfException() // 異常時(shí)重試
.retryIfResult(input -> input!=null && input instanceof Boolean && !Boolean.valueOf((Boolean) input)) // 返回值為false時(shí)重試
// 對(duì)應(yīng)Future獲取超時(shí)時(shí)間
.withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(4, TimeUnit.SECONDS,Executors.newFixedThreadPool(2))) //重試次數(shù)限制
.withRetryListener(new RetryListener() { // 重試執(zhí)行邏輯
@Override
public <V> void onRetry(Attempt<V> attempt) {
log.info("onRetry -> 重試次數(shù):{},距第一次重試時(shí)長(zhǎng):{}", attempt.getAttemptNumber(),attempt.getDelaySinceFirstAttempt());
if(attempt.hasException()){ // 是否異常導(dǎo)致重試
Throwable exception = attempt.getExceptionCause(); // 執(zhí)行的異常
log.info("異常:{}", exception);
}
if(attempt.hasResult()){ // 是否有返回
V result = attempt.getResult();
log.info("返回:{}",result);
}
}
})
// 控制每次重試間隔時(shí)間,如果AttemptTimeLimiter設(shè)置多線程
.withWaitStrategy(WaitStrategies.fixedWait(3,TimeUnit.SECONDS)) // 等待策略
.withBlockStrategy(BlockStrategies.threadSleepStrategy()) // 阻塞策略
//
.withStopStrategy(StopStrategies.stopAfterAttempt(5)) // 停止策略
.build();

使用Retryer讓業(yè)務(wù)代碼擁有重試能力

前兩次執(zhí)行時(shí)模擬返回false,則會(huì)執(zhí)行重試;當(dāng)?shù)?次時(shí),正常執(zhí)行業(yè)務(wù)代碼并返回true,結(jié)束重試。

@Test
public void retryWhenResult() throws ExecutionException, RetryException {
retryer.call(() -> {
if(counter.incrementAndGet() == 3){// 模擬前2此返回false,觸發(fā)重試
log.info(" 執(zhí)行業(yè)務(wù)代碼:{}次",counter.get());
return true;
}
return false;
});
}

模擬前3次出現(xiàn)異常,則會(huì)執(zhí)行重試;當(dāng)?shù)?次時(shí),正常執(zhí)行業(yè)務(wù)代碼,結(jié)束重試。

@Test
public void retryWhenException() throws ExecutionException, RetryException {
retryer.call(() -> {
if( counter.getAndIncrement() == 3 ){// 模擬前5此出現(xiàn)異常,觸發(fā)重試
return counter;
}
log.info(" 執(zhí)行業(yè)務(wù)代碼: {}次", counter.get());
throw new RuntimeException("ERROR");
});
}

模擬前5此出現(xiàn)異常,由于Retryer配置重試次數(shù)為5,則最終業(yè)務(wù)代碼不會(huì)執(zhí)行。

@Test
public void retryWhenResultOnFailure() throws ExecutionException, RetryException {
retryer.call(() -> {
if(counter.incrementAndGet() == 8){// 模擬前7此返回false,由于配置重試5次,因此最終失敗
log.info(" 執(zhí)行業(yè)務(wù)代碼:{}次",counter.get());
return true;
}
return false;
});
}

執(zhí)行流程

圖片

執(zhí)行流程

通過(guò)RetryerBuilder構(gòu)建Retryer,調(diào)用Retryer#call,封裝業(yè)務(wù)代碼為其回調(diào)函數(shù)。

  • 開(kāi)始循環(huán)執(zhí)行。
  • 由AttemptTimeLimiter#call執(zhí)行回調(diào)函數(shù)。
  • 將結(jié)果封裝為Attempt,包括兩種類(lèi)型ResultAttempt,ExceptionAttempt。如果成功,記錄執(zhí)行結(jié)果、持續(xù)時(shí)長(zhǎng);如果失敗,記錄異常、持續(xù)時(shí)長(zhǎng)。
  • 執(zhí)行監(jiān)聽(tīng)RetyrListener#onRetry,可以配置多個(gè)監(jiān)聽(tīng)。
  • 執(zhí)行拒絕斷言Predicate,根據(jù)返回值、執(zhí)行異常、返回異常類(lèi)型判斷是否終止重試。
  • 如果滿(mǎn)足條件,則繼續(xù)重試;否則結(jié)束重試,并返回Attempt包含回調(diào)結(jié)果。
  • 根據(jù)終止策略StopStrategy判斷是否終止重試。
  • 根據(jù)等待策略WaitStrategy獲取等待時(shí)長(zhǎng)。
  • 根據(jù)阻塞策略BlockStrategy與上一步等待時(shí)長(zhǎng)阻塞重試,如果出現(xiàn)異常則拋出RetryException。
  • 重復(fù)執(zhí)行以上邏輯。

配置

構(gòu)建Retryer主要通過(guò)RetryerBuilder.newBuilder()實(shí)現(xiàn),其相關(guān)配置如下:

配置

策略

名稱(chēng)

描述

AttemptTimeLimiters


任務(wù)執(zhí)行時(shí)長(zhǎng)限制



NoAttemptTimeLimit

無(wú)時(shí)長(zhǎng)限制



FixedAttemptTimeLimit

固定時(shí)長(zhǎng)限制


WaitStrategies


重試等待策略



ExponentialWaitStrategy

指數(shù)等待策略

按指數(shù)增加重試間隔時(shí)長(zhǎng),比如第一次2^1100、2^2100、2^3*100...最多300000


FibonacciWaitStrategy

斐波那契等待策略

1100、1100、2100、3100、5*100...


FixedWaitStrategy

固定時(shí)長(zhǎng)等待策略

按配置的固定間隔時(shí)間


RandomWaitStrategy

隨機(jī)時(shí)長(zhǎng)等待策略

隨機(jī)間隔時(shí)間,可以設(shè)置隨機(jī)值范圍


IncrementingWaitStrategy

遞增等待策略

根據(jù)配置的初始值與增量進(jìn)行累加時(shí)間


ExceptionWaitStrategy

異常等待策略

根據(jù)異常類(lèi)型指定等待時(shí)間


CompositeWaitStrategy

復(fù)合等待策略

可配置多個(gè)策略進(jìn)行組合

BlockStrategies


阻塞策略

根據(jù)WaitStrategies獲取阻塞時(shí)長(zhǎng)


ThreadSleepStrategy

線程等等策略

通過(guò)Thread.sleet()實(shí)現(xiàn)

StopStrategies


重試停止策略



NeverStopStrategy

無(wú)限制策略



StopAfterAttemptStrategy

限定次數(shù)策略



StopAfterDelayStrategy

限定時(shí)長(zhǎng)策略



NoAttemptTimeLimit

限定次數(shù)


注意

AttemptTimeLimiter中的FixedAttemptTimeLimit依賴(lài)于guava中的SimpleTimeLimiter,但是在guava高版本中該類(lèi)已經(jīng)成了私有類(lèi)。

總結(jié)

Guava Retrying模塊能夠通過(guò)簡(jiǎn)單的將代碼實(shí)現(xiàn)業(yè)務(wù)邏輯重試的功能,并且其配置中包含了重試的次數(shù)、時(shí)長(zhǎng)控制、重試阻塞、終止策略等等, 在項(xiàng)目中是非常常用的一項(xiàng)技術(shù)。


責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2022-07-05 11:48:47

MySQL死鎖表鎖

2009-11-03 08:56:02

linux死機(jī)操作系統(tǒng)

2022-12-19 11:31:57

緩存失效數(shù)據(jù)庫(kù)

2017-08-30 17:21:05

LinuxShell超時(shí)現(xiàn)象

2023-12-07 08:46:41

Kafka服務(wù)問(wèn)題網(wǎng)絡(luò)問(wèn)題

2021-10-30 19:01:17

磁盤(pán)字節(jié)文件

2011-11-18 10:52:00

2022-07-05 14:19:30

Spring接口CGLIB

2011-11-16 10:02:48

DNSDNS記錄DNS記錄消失

2018-01-28 20:39:39

戴爾

2020-07-10 08:46:26

HTTPS證書(shū)劫持網(wǎng)絡(luò)協(xié)議

2021-01-05 10:48:38

RedisAOF日志RDB快照

2024-08-06 08:08:14

2023-12-25 08:22:02

2018-01-30 15:08:05

2021-12-09 11:46:53

DockerIPLinux

2013-02-18 09:19:11

谷歌X PhoneNexus

2024-07-29 08:01:32

2024-08-06 12:29:23

2022-10-21 08:17:06

開(kāi)源項(xiàng)目閉源
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)