重试框架 -- Guava Retry

一般在各种业务场景中,为了保持系统稳定,我们都会有相应的重试机制,因为比如说,某个接口某个数据库链接由于网络抖动或者其他因素导致响应失败,这时候直接判定失败或者Mock数据未必是一种优雅的方式,因为这种情况下未必是接口挂掉了或者数据库连不上了,有可能是网络一时的抖动导致的,所以这时候一个优雅的重试机制或许能帮上我们。

Guava Retry

Guava Retry模块提供了一种通用方法, 可以使用Guava谓词匹配增强的特定停止、重试和异常处理功能来重试任意Java代码。

源码地址如下:

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
https://github.com/rholder/guava-retrying
Guava Retry优点

Guava retry工具与spring retry类似,都是通过定义重试者角色来包装正常逻辑重试,但是Guava retry有更优的策略定义,在支持重试次数和重试频度控制基础上,能够兼容支持多个异常或者自定义实体对象的重试源定义,让重试功能有更多的灵活性。

Guava Retryer也是线程安全的,入口调用逻辑采用的是 java.util.concurrent.Callable 的 call() 方法

maven 依赖

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
<!-- https://mvnrepository.com/artifact/com.github.rholder/guava-retrying -->
<dependency>
    <groupId>com.github.rholder</groupId>
    <artifactId>guava-retrying</artifactId>
    <version>2.0.0</version>
</dependency>
Guava retry Demo

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
@Slf4j
public class GuavaRetryDemo {
    public static void main(String[] args) {
        //定义请求实现
        Callable<Boolean> callable = () -> {
            // do something useful here
            log.info("call...");
            throw new RuntimeException();
        };

        //定义重试机制
        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                // retryIf 重试条件
                .retryIfResult(Objects::isNull)
                //设置异常重试源
                .retryIfExceptionOfType(IOException.class)
                .retryIfRuntimeException()
                .retryIfResult(res -> res = false)
                //设置等待间隔时间
                .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
                //设置最大重试次数
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                .build();
        try {
            retryer.call(callable);
        } catch (RetryException | ExecutionException e) {
            e.printStackTrace();
        }

    }
}

执行结果如下。

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
22:14:16.027 [main] INFO com.example.retry.demo.retry.guava.GuavaRetryDemo - call...
22:14:19.030 [main] INFO com.example.retry.demo.retry.guava.GuavaRetryDemo - call...
22:14:22.031 [main] INFO com.example.retry.demo.retry.guava.GuavaRetryDemo - call...
com.github.rholder.retry.RetryException: Retrying failed to complete successfully after 3 attempts.
    at com.github.rholder.retry.Retryer.call(Retryer.java:174)
    at com.example.retry.demo.retry.guava.GuavaRetryDemo.main(GuavaRetryDemo.java:42)
Caused by: java.lang.RuntimeException
    at com.example.retry.demo.retry.guava.GuavaRetryDemo.lambda$main$0(GuavaRetryDemo.java:25)
    at com.github.rholder.retry.AttemptTimeLimiters$NoAttemptTimeLimit.call(AttemptTimeLimiters.java:78)
    at com.github.rholder.retry.Retryer.call(Retryer.java:160)
    ... 1 more
永远重试

创建一个可以永远重试的 Retryer,在每次失败的重试之后,以递增指数的间隔等待直到最多5分钟。5分钟后,每隔5分钟重试一次。

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
        .retryIfExceptionOfType(IOException.class)
        .retryIfRuntimeException()
        .withWaitStrategy(WaitStrategies.exponentialWait(100, 5, TimeUnit.MINUTES))
        .withStopStrategy(StopStrategies.neverStop())
        .build();

创建一个可以永远重试的 Retryer,在每次失败的重试之后,增加斐波那契回退间隔,直到最多2分钟。2分钟后,每隔2分钟重试一次。

代码语言:javascript

代码运行次数:0

运行

AI代码解释

复制代码
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
        .retryIfExceptionOfType(IOException.class)
        .retryIfRuntimeException()
        .withWaitStrategy(WaitStrategies.fibonacciWait(100, 2, TimeUnit.MINUTES))
        .withStopStrategy(StopStrategies.neverStop())
        .build();
相关推荐
ss2733 分钟前
不用向量库,我用 MySQL 跑通了蔬菜 RAG--基于 RuoYi-AI 的蔬菜种植知识库 + 智能咨询系统,普通开发机就能跑
数据库·人工智能·智慧农业·ruoyi·知识库·rag
Franciz小测测29 分钟前
MySQL 增量备份实践:文件都在,为什么仍可能恢复失败?
数据库·mysql·binlog
2401_891409263 小时前
量化数据13:港股分钟K线、Level2逐笔Tick、十档盘口和港股通历史数据的批量提取
数据库
w-w0w-w10 小时前
SQL注入
网络·数据库·sql
tianyuanwo10 小时前
NetBox 数据库详解:当“关系型数据库”被装进一个网络运维的领域模型里
运维·数据库·netbox
一条泥憨鱼10 小时前
【计算机网络】短连接、长连接与连接池:从 TCP 握手到池化复用的完整链路
网络·数据库·网络协议·tcp/ip·计算机网络
IvorySQL10 小时前
深入 PostgreSQL WAL:从崩溃恢复到逻辑复制
数据库·postgresql
幽灵诶11 小时前
Mysql(基于测试的学习)
数据库·mysql
砚底藏山河12 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
宇宙无敌暴龙战士66612 小时前
MySQL 8 库表操作学习笔记:SQL 基础、库表管理、约束与用户授权全流程
数据库·sql·mysql·学习笔记·后端开发