【Guava】基于guava的重试组件Guava-Retryer转载
原创1.使用场景
在日常开发中,我们经常会遇到需要调用外部服务和接口的场景。外部服务对呼叫者来说一般是不可靠的,特别是在网络环境较差的情况下,网络抖动容易导致请求超时等异常情况,此时需要使用失败重试策略重新呼叫。 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 重试的方式真的很方便。
2.代码示例
以下是一份简短的清单。 guava-retrying 如何使用:
-
如果抛出 IOException 如果返回结果,请重试。 null 或者等于 2 重试,固定等待时间为 300 ms,最多尝试 3 次;
Callable
task = new Callable () { @Override public Integer call() throws Exception { return 2; } }; Retryer
retryer = RetryerBuilder. newBuilder() .retryIfResult(Predicates. 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,每次重试失败,打印日志;
@Override public Integer call() throws Exception { return 2; } };
Retryer
retryer = RetryerBuilder. newBuilder() .retryIfException() .withStopStrategy(StopStrategies.stopAfterDelay(30,TimeUnit.SECONDS)) .withWaitStrategy(WaitStrategies.incrementingWait(3, TimeUnit.SECONDS,1,TimeUnit.SECONDS)) .withAttemptTimeLimiter(AttemptTimeLimiters. fixedTimeLimit(3,TimeUnit.SECONDS)) .withRetryListener(new RetryListener() { @Override public void onRetry(Attempt attempt) { if (attempt.hasException()){ attempt.getExceptionCause().printStackTrace(); } } }) .build(); try { retryer.call(task); } catch (ExecutionException e) { e.printStackTrace(); } catch (RetryException e) { e.printStackTrace(); }
3.核心执行逻辑
long startTime = System.nanoTime();
for (int attemptNumber = 1; ; attemptNumber++) {
Attempt attempt;
try {
// 执行成功
V result = attemptTimeLimiter.call(callable);
attempt = new ResultAttempt(result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));
} catch (Throwable t) {
// 执行失败
attempt = new ExceptionAttempt(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)) {
throw new RetryException(attemptNumber, attempt);
} else {
// 计算下一次重试间隔
long sleepTime = waitStrategy.computeSleepTime(attempt);
try {
blockStrategy.block(sleepTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RetryException(attemptNumber, attempt);
}
}
}
4.依赖关系介绍
com.github.rholder
guava-retrying
2.0.0
默认的guava它也被包括在内。
5.主界面简介:
-
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 :复合持续时间等待策略;
作者:端木轩
链接:https://www.jianshu.com/p/d56c417d2b97
资料来源:简讯
版权归作者所有。请联系作者以获得商业转载的授权,并注明非商业转载的来源。
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除