重试框架 -- 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();
相关推荐
陌上丨2 小时前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
AI_56782 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw2 小时前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH30732 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道3 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
麦聪聊数据4 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务4 小时前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
Goat恶霸詹姆斯5 小时前
mysql常用语句
数据库·mysql·oracle
大模型玩家七七6 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
曾经的三心草6 小时前
redis-9-哨兵
数据库·redis·bootstrap