一、使用场景

在日常开发中,我们经常会遇到需要调用外部服务和接口的场景。外部服务对于调用者来说一般都是不可靠的,尤其是在网络环境比较差的情况下,网络抖动很容易导致请求超时等异常情况,这时候就需要使用失败重试策略重新调用 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 风格的重试方式真的很方便。

二、代码示例

以下会简单列出 guava-retrying 的使用方式:

  • 如果抛出 IOException 则重试,如果返回结果为 null 或者等于 2 则重试,固定等待时长为 300 ms,最多尝试 3 次;
Callable<Integer> task = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return 2;}
};Retryer<Integer> retryer = RetryerBuilder.<Integer>newBuilder().retryIfResult(Predicates.<Integer>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,每次重试失败,打印日志;
@Overridepublic Integer call() throws Exception {return 2;}
};Retryer<Integer> retryer = RetryerBuilder.<Integer>newBuilder().retryIfException().withStopStrategy(StopStrategies.stopAfterDelay(30,TimeUnit.SECONDS)).withWaitStrategy(WaitStrategies.incrementingWait(3, TimeUnit.SECONDS,1,TimeUnit.SECONDS)).withAttemptTimeLimiter(AttemptTimeLimiters.<Integer>fixedTimeLimit(3,TimeUnit.SECONDS)).withRetryListener(new RetryListener() {@Overridepublic <V> void onRetry(Attempt<V> attempt) {if (attempt.hasException()){attempt.getExceptionCause().printStackTrace();}}}).build();
try {retryer.call(task);
} catch (ExecutionException e) {e.printStackTrace();
} catch (RetryException e) {e.printStackTrace();
}

三、核心执行逻辑

long startTime = System.nanoTime();
for (int attemptNumber = 1; ; attemptNumber++) {Attempt<V> attempt;try {// 执行成功V result = attemptTimeLimiter.call(callable);attempt = new ResultAttempt<V>(result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));} catch (Throwable t) {// 执行失败attempt = new ExceptionAttempt<V>(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);}}
}

四、依赖引入

<dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>2.0.0</version>
</dependency>

默认的guava中也有包含。

五、主要接口介绍:

  • 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.cnblogs.com/f-zhao/p/7277988.html

【Guava】基于guava的重试组件Guava-Retryer相关推荐

  1. Google Guava Retry 优雅的重试方案

    Google Guava Retry 优雅的重试方案 前言 使用场景 什么场景不适合重试 了解幂等性 一.Guava Retry是什么? 与Spring retry比较 二.使用步骤 1.引入库 2. ...

  2. Spring-retry重试组件

    # 一.简介 Spring-retry 前面我们了解到了,Guava的重试组件,我们可以基于Guava的能力,来封装我们需要的能力来满足我们的业务.今天来分享Spring-Retry重试组件.当然Sp ...

  3. 第04篇:Guava-retry重试组件

    作者: 西魏陶渊明 博客: https://blog.springlearn.cn/ 西魏陶渊明 天下代码一大抄, 抄来抄去有提高, 看你会抄不会抄! 一.简介 Guava-retry Guava 是 ...

  4. 从0到1带你手撸一个请求重试组件,不信你学不会!

    点击关注公众号,实用技术文章及时了解 背景介绍 在实际的项目应用场景中,经常会需要遇到远程服务接口的调用,时不时会出现一些接口调用超时,或者函数执行失败需要重试的情况,例如下边的这种场景: 某些不太稳 ...

  5. Visifire Silverlight Charts (基于SilverLight的Chart组件)

    偶然发现了这个东东,一个基于SilverLight的Chart组件,遵循GPL v3,支持的Chart类型挺多的(支持饼图,柱状图,圈图,区图等等). Visifire 有比较完善的文档, 而且还有一 ...

  6. 如何开发一个基于 Vue 的 ui 组件库

    如何开发一个基于 Vue 的 ui 组件库 开发模式 预览 demo 在开发一个 ui 组件库时,肯定需要一边预览 demo,一边修改代码. 常见的解决方案是像开发一般项目一样使用 webpack-d ...

  7. 基于Java Swing JFream 组件的趣味推箱子小游戏

    一 需求分析 设计一个经典的推箱子小游戏,在窗体里有墙,箱子,胜利的标志,和工人,用户可以通过键盘上的"上"."下"."左"."右 ...

  8. [源码和文档分享]基于Java Swing JFream 组件的趣味推箱子小游戏

    一 需求分析 设计一个经典的推箱子小游戏,在窗体里有墙,箱子,胜利的标志,和工人,用户可以通过键盘上的"上"."下"."左"."右 ...

  9. 基于Vue结合Vant组件库的仿电影APP

    Vue综合案例 Vue综合案例 一.项目概要 1.效果前瞻 2.开发流程 3.开发环境 二.初始化及必要知识点 1.初始化远程仓库 2.创建项目 3.路由规划 4.反向代理配置 5.网络请求封装 6. ...

  10. 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)...

    背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...

最新文章

  1. 时间复杂度和空间复杂度3 - 数据结构和算法05
  2. 在 echarts关系图动态线上添加文字_多折线堆叠图如何制作?
  3. 计算机组成原理考试复习
  4. SSL 1108——【USACO 2.1】海明码(DFS)
  5. WPF老矣,尚能饭否——且说说WPF今生未来(中):策略
  6. 随机森林原始论文_【论文笔记】韩家炜团队AutoPhrase:从大量文本库中 自动挖掘短语...
  7. wpa_supplicant中配置TTLS网络的phase2参数
  8. java无法定位程序点_无法定位程序输入点是什么意思
  9. python实现爬取12306所有站点及其编码信息(附源代码)!
  10. 探索式测试方法的实践
  11. 哨兵-1 Sentinel-1数据下载(欧空局)
  12. 使用vscode编写html代码
  13. simucpp:C++搭建微分方程求解器框架(重写simulink)
  14. 游族马寅龙:常见信息安全风险及应对方案
  15. AngularJs 最新验证手机号码,成功测试通过
  16. 福建省计算机二级知识点,福建省计算机二级语言复习资料.doc
  17. 名创优品“超级能打”背后的平价主义与飞轮效应
  18. AP微积分到底选AB还是BC?
  19. apache php 调优_性能优化之PHP优化
  20. Jmeter简介下载安装

热门文章

  1. MyBatis中一对多和多对一处理
  2. Nacos集群(二)阿里自研弱一致性Distro协议核心实现
  3. 企业网盘2016年度深度盘点,哪家才是NO.1?
  4. @Autowired与@Resource的差别
  5. [算法题] 安排会议室——贪心算法的应用
  6. Illegal use of when-style tag without ...
  7. 所有浏览器的 CSS selectors 兼容性
  8. Windows 8 to Go
  9. shell字符串的截取的问题
  10. 正则表达式匹配EXCEL地址字符串