Spring Boot 引入 Guava Retry 实现重试机制

news2024/11/15 8:45:42

为什么要用重试机制

在如今的系统开发中,为了保证接口调用的稳定性和数据的一致性常常会引入许多第三方的库。就拿缓存和数据库一致性这个问题来说,就有很多的实现方案,如先更新数据库再删除缓存、先更新缓存再更新数据库,又或者是异步缓存写入。然而某些场景下出现更新数据库成功,但删除缓存失败,又或者是更新缓存失败但更新数据库失败了。因此为保证缓存数据库的一致性,我们可以尝试引入重试机制来实现,当数据库更新成功后去删除缓存,如果删除失败就进行重试。

引入 Guava Retry 库实现重试机制

引入依赖

在引入依赖前,先创建一个 Spring Boot 工程,这里我就不演示了。

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

编写重试器的配置类

常见的重试策略

  1. 重试间隔时间,等待进入下一次重试的时间
  2. 重试的次数,超过设定次数就停止重试
  3. 重试的时间限制,规定重试时的时间限制,若重试过程中超过了这个时间就会抛出异常
  4. 重试时机,表明在什么场景需要重试,是抛出异常、还是返回 true,还是返回 false 呢。

在 config 包下编写一个重试器的配置类,设置重试的策略,当我们想在项目中使用时直接注入其依赖即可。

@Configuration
public class RetryConfig {

    @Bean
    public Retryer<Boolean> retryer() {
        return RetryerBuilder.<Boolean>newBuilder()
                .retryIfExceptionOfType(Exception.class) // 设置出现 Exception 异常就重试
                .retryIfResult(Predicates.equalTo(false)) // 设置结果为 false 才重试
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS)) // 设置每次重试间隔为 2s
                .withStopStrategy(StopStrategies.stopAfterAttempt(2)) // 设置重试次数为 2 次,超过 2 次就停止
                .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(3, TimeUnit.SECONDS)) // 设置每次重试的时间限制为 3s
                .build();
    }
}

直接引入 Bean 进行重试

创建一个 SpringBoot 的测试类,再注入入 Retryer 的 Bean。我写了一个方法来判断生成的随机数是否大于 10,大于就返回 true,否则返回 false,同时还打印重试的次数,如果第一次调这个函数就返回 true 的话就只重试了一次,因为每调用一次算一次重试,即 i == 1。

@SpringBootTest
public class RetryerTest {

    @Resource
    private Retryer<Boolean> retryer;

    private int i = 1;

    @Test
    public void test() {
        try {
            retryer.call(() -> isGreaterThan10());
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (RetryException e) { // 超过指定的重试次数、超过的最大等待时间或超过重试时间就会抛这个异常
            throw new RuntimeException(e);
        }
    }

    // 判断生成的随机数是否大于 10
    private boolean isGreaterThan10() {
        Random random = new Random();
        System.out.println("重试次数:" + i++);
        int num = random.nextInt();
        System.out.println(num);
        return num > 10;
    }

}

从测试结果就可以看出来,重试次数为 1,因为第一次调用就返回了 true。

再改造一下,看看它超过了规定的重试次数(这里我规定的是两次)会发生什么?

public class RetryerTest {

    @Resource
    private Retryer<Boolean> retryer;

    private int i = 1;

    @Test
    public void test() {
        try {
            retryer.call(() -> isGreaterThan1000000000());
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (RetryException e) { // 超过指定的重试次数、超过的最大等待时间或超过重试时间就会抛这个异常
            throw new RuntimeException(e);
        }
    }

    // 判断生成的随机数是否大于 1000000000
    private boolean isGreaterThan1000000000() {
        Random random = new Random();
        System.out.println("重试次数:" + i++);
        int num = random.nextInt();
        System.out.println(num);
        return num > 1000000000;
    }

}

从结果我们看出,调用两次后就抛出异常了,这个异常就是 RetryException,当超过指定的重试次数、超过的最大等待时间或超过重试时间就会抛这个异常。

当然这个方法写的不严谨,因为生成的数是随机的,如果两次生成的数都大于 1000000000,就不会抛出异常,要是第一次生成的数就大于 1000000000,那就只重试了一次。当然意思到了就行,具体的话就看你业务是啥样了,然后你再去调整就好了。

 

开源项目

前一阵子,我开源了一个既好玩又能学到东西的项目,有兴趣的同学可以移步学习和体验哈——我终于有我的开源项目了!!!-CSDN博客。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1950301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

江苏省发改委副主任钱海云一行莅临我司调研指导

近日&#xff0c;江苏省发改委副主任钱海云、支援合作处副处长卢桐、调研员鲁培和一行&#xff0c;在江宁开发区管委会及市、区发改委有关负责人陪同下&#xff0c;莅临南京天洑软件有限公司走访调研。天洑软件总工程师郭阳博士携管理层参与本次调研活动。 在参观过程中&#x…

【C++】选择结构- 嵌套if语句

嵌套if语句的语法格式&#xff1a; if(条件1) { if(条件1满足后判断是否满足此条件) {条件2满足后执行的操作} else {条件2不满足执行的操作} } 下面是一个实例 #include<iostream> using namespace std;int main4() {/*提示用户输入一个高考分数&#xff0c;根据分…

通过 Function-Call Input Events启用图表中的控制状态

在由function-call input event启用的图表中&#xff0c;可以通过设置启用图表时的状态属性来控制状态的行为。根据此属性的值&#xff0c;当输入事件重新启用图表时&#xff0c;状态要么保持其最新值&#xff0c;要么恢复为初始值。要修改属性&#xff0c;请执行以下操作&…

一文读懂《制造业数字化转型行动方案》

​在推动新型工业化与构建现代化产业体系的宏伟蓝图中&#xff0c;制造业的数字化转型无疑是至关重要的一环。随着国务院常务会议正式批准《制造业数字化转型行动方案》&#xff08;简称《方案》&#xff09;&#xff0c;标志着我国制造业正式迈入了一个全面拥抱数字化、智能化…

C++迈向精通:STL-iterator_traits迭代器类型萃取解析

STL-iterator_traits迭代器类型萃取解析 源码 在阅读STL源码的时候遇到了这样的一行代码&#xff1a; 通过ctags跳转到对应的定义区域&#xff1a; 下面还有两个特化版本&#xff1a; 根据英文释义&#xff0c;发现模板中需要传入的是一个迭代器类型&#xff0c;在上面找到源…

NAND Flash 的 SDR、ONFI、DDR 接口

NAND Flash 的 SDR、ONFI、DDR 接口 1. 省流导图 2. SDR、ONFI、DDR 概述 2.1 SDR (Single Data Rate) SDR&#xff08;Single Data Rate&#xff09;是指读写数据使用 单个时钟信号的边缘&#xff0c;即上升沿或下降沿 。在 SDR 模式下&#xff0c;数据的传输速率受限于时钟…

用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC]

文章目录 用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现用友U8 Cloud MeasureQueryFrameAction接口处SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿…

【Gin】深度解析:在Gin框架中优化应用程序流程的责任链设计模式(上)

【Gin】深度解析&#xff1a;在Gin框架中优化应用程序流程的责任链设计模式(上) 大家好 我是寸铁&#x1f44a; 【Gin】深度解析&#xff1a;在Gin框架中优化应用程序流程的责任链设计模式(上)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 本次文章分为上下两部分&#xf…

Jenkins的相关概述和安装

Jenkins 1.什么是jenkins Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。耗内存max 2. 为什么使用Jenkins 拉取、编译、打包…

AI绘画入门实践|Midjourney:使用 --no 去除不想要的物体

在 Midjourney 中&#xff0c;--no 作为反向提示词&#xff0c;告诉 MJ 在生成图像时&#xff0c;不要包含什么。 使用格式&#xff1a;--no 对应物体提示词&#xff08;多个物体之间使用","间隔&#xff09; 使用演示 a web banner, summer holiday --v 6.0 a web b…

变阻器在实际应用中需要注意哪些安全事项?

变阻器是广泛应用于电子设备中的电子元件&#xff0c;它可以改变电阻值以控制电流的大小。然而&#xff0c;在实际应用中&#xff0c;如果操作不当&#xff0c;可能会引发一些安全问题。因此&#xff0c;使用变阻器时&#xff0c;必须注意以下安全事项&#xff1a; 1. 选择合适…

windows wsl ubuntu系统安装桌面可视化

参考&#xff1a; https://www.bilibili.com/read/cv33557374/ 1&#xff09;首先先安装好wsl ubuntu系统 2&#xff09;安装 Ubuntu 桌面版 sudo apt purge -y acpid acpi-support modemmanagersudo apt-mark hold acpid acpi-support modemmanager sudo apt install ubunt…

UE4如何直接调试Game

某些功能在编辑器里不好调试&#xff0c;例如Pak&#xff0c;就需要直接调试 Game&#xff0c;做法是选择 Game&#xff0c;不要选择Client&#xff0c;加断点&#xff0c;然后点击 Debug 就好了。 断点调试成功&#xff1a; 同时看到界面&#xff1a;

中国森林地上和地下生物量碳变化数据集(2002-2021年)

中国森林地上和地下生物量碳变化数据集&#xff08;2002-2021年&#xff09; 数据介绍 为了量化中国近期全国性恢复工作的生态后果&#xff0c;过去20年森林生物量碳储量变化的空间显性信息至关重要。然而&#xff0c;在全国范围内进行长期生物量追踪仍然具有挑战性&#xff0c…

网络安全防御【IPsec VPN搭建】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤&#xff1a; 修改双机热备的为主备模式&#xff1a; 2、配置交换机LSW6新增的配置&#xff1a; 3、防火墙&#xff08;FW4&#xff09;做相关的基础配置&#xff1a; 4、搭建IPsec VPN通道 &#xff08;1…

LINUX -exec函数族

1、功能&#xff1a; *让父子进程来执行不相干的操作 *能够替换进程地址空间的代码.text段 *执行另外的程序&#xff0c;不需要创建额外的的地址空间 *当前程序中调用另外一个应用程序 2、执行目录下的程序&#xff1a; *指定执行目录下的程序 int execl(const char *path,…

JavaSE从零开始到精通(九) - 双列集合

1.前言 Java 中的双列集合主要指的是可以存储键值对的集合类型&#xff0c;其中最常用的包括 Map 接口及其实现类。这些集合允许你以键值对的形式存储和管理数据&#xff0c;提供了便捷的按键访问值的方式。 2. HashMap HashMap 是基于哈希表实现的 Map 接口的类&#xff0c…

软件测试中的压力测试和性能测试区别

压力测试和性能测试是软件测试中两种重要的测试类型&#xff0c;它们都旨在评估软件在不同条件下的表现&#xff0c;但侧重点和目的有所不同。 压力测试&#xff08;Stress Testing&#xff09;定义&#xff1a; 压力测试是一种测试方法&#xff0c;用于确定软件在极端条件下…

【C++指南】类和对象(上)

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注

网格大师将OSGB转3Dtiles是否用了LOD以及顶层重建?

答&#xff1a;如果勾选合并根节点&#xff0c;是有用到LOD以及顶层重建的。 网格大师是一款能够解决实景三维模型空间参考、原点、瓦块大小不统一&#xff0c;重叠区域处理问题的工具“百宝箱”&#xff0c;集格式转换、坐标转换、轻量化、瓦片重划分等多功能优势于一身&#…