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

为什么要用重试机制

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

引入 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 {@Beanpublic 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 {@Resourceprivate Retryer<Boolean> retryer;private int i = 1;@Testpublic void test() {try {retryer.call(() -> isGreaterThan10());} catch (ExecutionException e) {throw new RuntimeException(e);} catch (RetryException e) { // 超过指定的重试次数、超过的最大等待时间或超过重试时间就会抛这个异常throw new RuntimeException(e);}}// 判断生成的随机数是否大于 10private 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 {@Resourceprivate Retryer<Boolean> retryer;private int i = 1;@Testpublic void test() {try {retryer.call(() -> isGreaterThan1000000000());} catch (ExecutionException e) {throw new RuntimeException(e);} catch (RetryException e) { // 超过指定的重试次数、超过的最大等待时间或超过重试时间就会抛这个异常throw new RuntimeException(e);}}// 判断生成的随机数是否大于 1000000000private 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://xiahunao.cn/news/3267531.html

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

相关文章

C++ | Leetcode C++题解之第278题第一个错误的版本

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstBadVersion(int n) {int left 1, right n;while (left < right) { // 循环直至区间左右端点相同int mid left (right - left) / 2; // 防止计算时溢出if (isBadVersion(mid)) {right mid; // 答案…

错误解决 error CS0117: ‘Buffer‘ does not contain a definition for ‘BlockCopy‘

Unity 2022.3.9f1 导入 Runtime OBJ Importer 后出现&#xff1a; error CS0117: ‘Buffer’ does not contain a definition for ‘BlockCopy’ 解决办法&#xff1a; 源代码&#xff1a; int DDS_HEADER_SIZE 128; byte[] dxtBytes new byte[ddsBytes.Length - DDS_HEAD…

MediatR 使用记录-发布订阅运行机制测试

注意&#xff1a;mediatR发布-订阅&#xff0c;订阅方是多个的时候是串行的&#xff0c;一个执行完才执行下一个 // 发送部分代码Console.WriteLine($"{DateTime.Now}-发送开始-");mediator.Publish<TestEvent>(new TestEvent("nancy"));Console.Wr…

HarmonyOS NEXT零基础入门到实战-第四部分

自定义组件: 概念: 由框架直接提供的称为 系统组件&#xff0c; 由开发者定义的称为 自定义组件。 源代码&#xff1a; Component struct MyCom { build() { Column() { Text(我是一个自定义组件) } } } Component struct MyHeader { build() { Row(…

Charles的使用配置(二)

Charles基础设置 抓包端口&#xff1a;Proxy->Proxy settings,全部选 设置系统的代理服务器 Charles电脑证书配置 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/304c604776bc45d59463c621c5a097e6.png Charles端设置SSL的端口 Proxy->ssl Proxying…

MSP430芯片解锁 以立创开发板 ti开发板为例

参考自无名小哥的ppt第二部分自下而上读 b站视频讲解&#xff1a;

安卓嘀嗒清单v7.2.2.2高级版

软件介绍 TickTick是一款轻便高效的任务管理、日程管理&#xff08;GTD&#xff09;和时间管理应用&#xff0c;配备强大的记事和提醒功能。你可以在手机、平板、网页等多达11个平台上使用滴答清单记录大小事务、制定工作计划、整理购物清单、设置生日提醒&#xff0c;甚至安排…

【React】项目的目录结构全面指南

文章目录 一、React 项目的基本目录结构1. node_modules2. public3. src4. App.js5. index.js6. .gitignore7. package.json8. README.md 二、React 项目的高级目录结构1. api2. hooks3. pages4. redux5. utils 三、最佳实践 在开发一个 React 项目时&#xff0c;良好的目录结构…

SpringCloud注册中心

SpringCloud注册中心 文章目录 SpringCloud注册中心1、注册中心原理2、Nacos注册中心2.1、部署nacos 3、服务注册4、服务发现 1、注册中心原理 在大型微服务项目中&#xff0c;服务提供者的数量会非常多&#xff0c;为了管理这些服务就引入了注册中心的概念。注册中心、服务提…

【数据结构】链表之LinkedList(无头双链表实现 + 详解 + 原码)

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

让你的程序有记忆功能。

目录 环境 代码 环境 大语言模型&#xff1a; gpt-40-mini Mem0: Empower your AI applications with long-term memory and personalization OpenAPI-Key: Mem0-Key&#xff1a; 代码 import osfrom dotenv import load_dotenv from openai import OpenAI from m…

ili9341数据手册中的常用命令

一.设置液晶显示窗口 根据液晶屏的要求&#xff0c;在发送显示数据前&#xff0c;需要先设置显示窗口确定后面发送的像素数据的显示区域。下面的0x2A和0x2B分别对应的是y轴与x轴的命令。 /********** ILI934 命令 ********************************/ #define CMD_SetCoor…

【深度学习】LLaMA-Factory 大模型微调工具, 大模型GLM-4-9B Chat ,微调与部署 (2)

文章目录 数据准备chat评估模型导出模型部署总结 资料&#xff1a; https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md https://www.53ai.com/news/qianyanjishu/2015.html 代码拉取&#xff1a; git clone https://github.com/hiyouga/LLaMA-Factory.git cd …

Qt SQLite数据库编程学习总结

到此为止&#xff0c;就使用Qt进行SQLite数据库的操作&#xff0c;做一次总结 1. Qt中数据库操作的相关概念和类 Qt 数据库编程相关基本概念https://blog.csdn.net/castlooo/article/details/140497177 2.表的只读查询--QSqlQueryModel QSqlQueryModel单表查询的使用总结htt…

AI驱动的在线面试系统:技术革新与初步面试的新体验

一、引言 在数字化和智能化的时代背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术正日益渗透到各行各业&#xff0c;为人们的生活和工作带来前所未有的变革。其中&#xff0c;AI驱动的在线面试系统&#xff0c;凭借其高效、便捷、公正等特性&#xff0c;逐渐成为企业…

示例:WPF中如何处理TabControl页面绑定ItemsSource切换TabItem时UI数据没有持久保存的问题

一、目的&#xff1a;在WPF开发过程中&#xff0c;经常用到TabControl&#xff0c;也会遇到类似问题&#xff0c;用TabControl绑定数据源ItemsSource时&#xff0c;切换TabItem时&#xff0c;UI上的数据没有持久保存&#xff0c;本文介绍一种处理方式&#xff0c;可以做到缓存页…

Elasticsearch概念及ELK安装

1、Elasticsearch是什么 它是elastic技术栈中的一部分。完整的技术栈包括&#xff1a; Elasticsearch&#xff1a;用于数据存储、计算和搜索 Logstash/Beats&#xff1a;用于数据收集 Kibana&#xff1a;用于数据可视化 整套技术栈被称为ELK&#xff0c;经常用来做日志收集…

海康4G摄像头接入自定义程序

1.使用【萤石云视频】APP添加摄像头&#xff0c;在设置中关闭视频加密 2.打开萤石云&#xff0c;进入控制台 3.设备管理中可以看到添加的设备 4.添加一个应用&#xff0c;即可获取AppKey、Secret、AccessToken 5.根据文档中的说明获取播放地址&#xff0c;这里是我生成的播放…

单证不一致清关难题 | 国际贸易综合服务平台 | 箱讯科技

什么是单证一致&#xff1f; 单证一致出口方所提供的所有单据要严格符合进口方开证银行所开信用证的要求&#xff0c;或者说出口方制作和提供的所有与本项货物买卖有关的单据&#xff0c;与进口方申请开立的信用证对单据的要求完全吻合&#xff0c;没有矛盾。 添加图片注释&am…

本地搭建rtmp拉流

本地搭建rtmp拉流 可按照步骤来 关注公众号&#xff1a;城羽海 更多有趣实用教程 下载地址: 从微信公众号发送关键词 rtmp可获取下载地址 文章目录 本地搭建rtmp拉流 可按照步骤来 关注公众号&#xff1a;城羽海 更多有趣实用教程 拿到之后如图所下&#xff1f;二、配置obs文…