概述
本文将介绍 guava-retrying 是什么,有什么用,以及如何在项目中合理运用。
- guava-retrying 是一个线程安全的 Java 重试类库,提供了一种通用方法去处理任意需要重试的代码。
- 可以方便灵活地控制重试次数、重试时机、重试频率、停止时机等,并具有异常处理功能。
主要包括以下内容:
- guava-retrying 的关键点
- guava-retrying 的 maven 依赖
- 使用场景分析
- 基本使用
- guava-retrying 原理解析
- 具体的使用场景案例
- 在 spring boot 中的使用
guava-retrying 的关键点
- 将业务逻辑封装到实现了 Callable 接口的 call 方法中
- 支持设置当遇到什么异常的时候进行重试操作(也就是重新执行 Callable 接口的 call 方法)
- 支持设置当 call 方法的返回结果不符合预期的时候进行重试操作
- 支持设置重试的次数
- 支持设置每次重试后的等待时间
- 通过构造器模式创建重试对象 Retryer
guava-retrying 的 maven 依赖
1 | <dependency> |
使用场景分析
- 由于网络问题需要重试
- 某个任务的执行时间比较长,可以通过重试来不断检查执行结果是否完成
基本使用
定义业务逻辑
- 业务逻辑封装在 Callable 对象中。
1 | Callable<Boolean> callable = () -> { |
定义重试器
- 通过构造器模式创建一个 Retryer 重试器对象
1 | // 定义重试器 |
通过重试器来执行代码
- 通过重试器的 call 方法执行业务逻辑代码
1 | try { |
- 也可以通过 wrap 方法返回 RetryerCallable 对象,之后再通过 RetryerCallable 对象中的 call 执行业务逻辑
1 | try { |
分析上述代码:
- 首先定义了一个 Callable 对象,其中执行我们需要重试的业务逻辑。
- 通过 RetryerBuilder 构造重试器,构造包含如下部分:
1 | 重试条件 retryIfResult、retryIfExceptionOfType、retryIfRuntimeException |
- 通过 retryer.call 执行任务
- 当重试次数超过设定值或者被强制中断时,会抛出异常,需要捕获处理
guava-retrying 原理解析
下面是 guava-retrying 的 call 方法的解析
1 | public V call(Callable<V> callable) throws ExecutionException, RetryException { |
具体的使用场景案例
在下面的案例中通过 MyRetryListener 来监听重试的过程,定义如下
1 | public static class MyRetryListener implements RetryListener { |
执行的结果为空的情况下重试
- 测试代码如下
1 |
|
- 通过监听发现重试的原因是:结果为空,具体如下
1 | 13:09:30.736 [main] INFO com.ckjava.retrying.TestRetrying - 执行结果:null, 异常:null, 当前重试次数:1, 当前累计执行时长:3003 毫秒 |
出现异常的情况下重试
- 测试代码如下
1 |
|
- 通过监听发现重试的原因是:出现了异常,具体如下
1 | 13:11:31.581 [main] INFO com.ckjava.retrying.TestRetrying - 执行结果:null, 异常:com.ckjava.retrying.TestRetrying$MyException, 当前重试次数:1, 当前累计执行时长:3009 毫秒 |
在 SpringBoot 中的使用
这里通过调用其他应用的 api 来举例说明具体的使用。
通过@Configuration
配置类定义重试器
1 | package com.toulezu.test.config; |
定义业务逻辑
1 | package com.toulezu.test.function; |
通过重试器执行业务逻辑
1 | package com.toulezu.test.web; |