5分钟攻略Spring-Retry框架实现经典重试场景

前言

今天分享干货,控制了篇幅,5分钟内就能看完学会。

主题是Spring-Retry框架的应用,做了一个很清晰的案例,代码可下载自测。

框架介绍

Spring-Retry框架是Spring自带的功能,具备间隔重试包含异常排除异常控制重试频率等特点,是项目开发中很实用的一种框架。

本篇所用框架的版本如下:

技术版本
Java17
SpringBoot3.2
Spring-retry2.0.4

正文

1、引入依赖

坑点:需要引入AOP,否则会抛异常。

<!-- Spring-Retry -->
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>
<!-- Spring-AOP -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、启动类注解

坑点:很容易一时疏忽忘记启动类开启@EnableRetry,大家别忘了哦。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;@SpringBootApplication
@EnableRetry
public class SpringRetryDemoApplication {public static void main(String[] args) {SpringApplication.run(SpringRetryDemoApplication.class, args);}}
3、模拟发短信

我们模拟一个发短信功能,根据随机数分别作为成功、失败、抛出各种异常的入口。

这里抛出几种异常的目的,是为了后面演示出重试注解参数产生的效果。

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;/*** <p>* 短信服务工具类* </p>** @author 程序员济癫* @since 2023-12-21 09:40*/
@Slf4j
public class SmsUtil {/*** 发送短信*/public static boolean sendSms() {// 使用随机数模拟重试场景int num = RandomUtil.randomInt(4);log.info("[SmsUtil][sendSms]>>>> random num = {}", num);return switch (num) {case 0 ->// 模拟发生参数异常throw new IllegalArgumentException("参数有误!");case 1 ->// 模拟发生数组越界异常throw new ArrayIndexOutOfBoundsException("数组越界!");case 2 ->// 模拟成功true;case 3 ->// 模拟发生空指针界异常throw new NullPointerException();default ->// 未成功则返回falsefalse;};}
}
4、Retry应用

我们单独写一个用于重试调用的组件类,用于业务类调用。

import com.example.springretrydemo.util.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** <p>* 重试组件* </p>** @author 程序员济癫* @since 2023-12-21 09:43*/
@Slf4j
@Component
public class RetryComponent {/*** 重试机制发送短信*/@Retryable(retryFor = {IllegalArgumentException.class, ArrayIndexOutOfBoundsException.class},noRetryFor = {NullPointerException.class},maxAttempts = 4,backoff = @Backoff(delay = 2000L, multiplier = 2))public boolean sendSmsRetry() {log.info("[RetryComponent][sendSmsRetry]>>>> 当前时间:{}", getNowTime());return SmsUtil.sendSms();}/*** 兜底方法,规则:*        1、超出了最大重试次数;*        2、抛出了不进行重试的异常;*/@Recoverpublic boolean recover() {log.info("[RetryComponent][recover]>>>> 短信发送次数过多,请稍后重试!");return false;}/*** 获取当前时间*/private String getNowTime() {return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));}
}

@Retryable注解参数说明:

  • retryFor:此参数包含的异常会触发重试机制,多个异常则以数组形式定义。
  • noRetryFor:此参数包含的异常不会触发重试机制,多个异常则以数组形式定义。
  • maxAttempts:重试最大次数,不定义则默认3次。
  • backoff:定义补偿机制,delay-延迟时间(s),multiplier-重试时间的倍数(比如设置为2,重试4次的话,补偿机制就是分别间隔2s、4s、8s做重试)

@Recover注解说明:用于兜底,当 超出了最大重试次数抛出了不进行重试的异常 时,直接执行该注解声明的兜底方法。

PS:顺便提一句,如果是 SpringBoot2.x 的版本,这里@Retryable注解的retryFor参数对应的是includenoRetryFor参数对应的是exclude,可以直接点进去看源码便一目了然。


5、JunitTest测试

我们编写一个Junit测试类来测试重试的效果,并打印出结果信息。

import com.example.springretrydemo.retry.RetryComponent;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@Slf4j
@SpringBootTest
class SpringRetryDemoApplicationTests {@Autowiredprivate RetryComponent retryComponent;@Testvoid sendSmsTest() {boolean ret = retryComponent.sendSmsRetry();log.info("sendSmsTest result = {}", ret);}}
6、效果

第1次测试时,可以看到,随机数刚好都是1,走的是数组越界异常。

而这个异常在retryFor中定义了,所以执行了4次,直到结束,最后进入了兜底方法。

同时,可以看到,执行4次的频率也和预想一样是2s、4s、8s。

image

第2次测试时,可以看到,随机数是3,走的是空指针异常。

而这个异常在noRetryFor中定义了,所以接下来直接进入了兜底方法。

image

第3次测试时,可以看到,第一次随机数是0,走的参数异常,在retryFor中,所以2s后继续重试。

然后随机数是2,表示业务成功,所以直接返回了true。

这个场景就很像大家经常遇见的补偿操作,第一次发生异常失败,第二次重试后又成功了。

image

总结

Spring-retry框架还是挺实用的,但不是万能的。

优点是,简化了重试逻辑,提供了现成的重试策略,具备一定灵活性。

缺点,也很明显,生产环境使用有风险,比如在复杂场景下配置的策略有问题,有可能会导致无限重试,这个后果不用说大家也能想象。

所以,使用这个框架,一定要明确好场景再使用,我这里不推荐复杂场景下使用,因为君子不立于危墙之下

好了,今天的知识点你学会了吗?

完整代码:戳这里 --> Gitee


喜欢请点赞+关注↑↑↑,持续分享干货哦~

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八:爬虫-MySQL基础

一&#xff1a;MySQL数据库基础 1.MySQL数据库介绍 MySQL是一个[关系型数据库管理系统]&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Rela…

物业服务投诉反馈建议建议二维码

为高效处理物业方面的投诉问题&#xff0c;进一步提升居住品质。凡尔码平台推出“二维码”便民投诉、反馈方式&#xff0c;如有群租扰民、占用堵塞消防通道或私拉乱建等问题&#xff0c;可以立即扫码或进入“凡尔码”小程序进行投诉或反馈。 如电梯出现故障物业服务企业未及时维…

【机器学习实战】基于python对泰坦尼克幸存者进行数据分析与预测

&#x1f4da;引言 &#x1f64b;‍♂️作者简介&#xff1a;生鱼同学&#xff0c;大数据科学与技术专业硕士在读&#x1f468;‍&#x1f393;&#xff0c;曾获得华为杯数学建模国家二等奖&#x1f3c6;&#xff0c;MathorCup 数学建模竞赛国家二等奖&#x1f3c5;&#xff0c…

智能DJ软件Algoriddim djay Pro AI mac功能特点

Algoriddim djay Pro AI mac是一款具有人工智能功能的 DJ 软件&#xff0c;它可以让 DJ 在演出时更加灵活、创意和自由。 Algoriddim djay Pro AI mac主要特点 人工智能智能排列功能&#xff1a;djay Pro AI 可以根据 BPM、音调和热度等因素&#xff0c;将曲目按照最优顺序排列…

ArcTS组件:图片、文本、文本框

图片组件 文本 文本输入框

基于JSP+Servlet+Mysql的学生信息管理系统

基于JSPServletMysql的学生信息管理系统 一、系统介绍二、功能展示1.目录2.数据库3.登陆4.注册5.主页 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目名称&#xff1a;基于JSPServletMysql的学生信息管理系统 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语…

IspSrver-DNS

2023年全国网络系统管理赛项真题 模块B-Windows解析 题目 安装DNS服务器,根据题目创建必要正向区域和反向区域的DNS解析。把当前机器作为互联网根域服务器,创建test1.com~test100.com,并在所有正向区域中创建一条A记录,解析到本机地址。配置步骤 安装DNS服务器,根据题目创…

深入了解Spring MVC工作流程

目录 1. MVC架构简介 2. Spring MVC的工作流程 2.1. 客户端请求的处理 2.2. 视图解析和渲染 2.3. 响应生成与返回 3. Spring MVC的关键组件 3.1. DispatcherServlet 3.2. HandlerMapping 3.3. Controller 3.4. ViewResolver 4. 结论 Spring MVC&#xff08;Model-Vi…

【SpringBoot篇】解决缓存击穿问题① — 基于互斥锁方式

文章目录 &#x1f339;什么是缓存击穿&#x1f33a;基于互斥锁解决问题&#x1f6f8;思路 &#x1f3f3;️‍&#x1f308;代码实现 &#x1f339;什么是缓存击穿 缓存击穿是指在使用缓存系统时&#xff0c;对一个热点数据的高并发请求导致缓存失效&#xff0c;多个请求同时访…

anconda常用命令

一、基础指令说明 1、查看anconda版本号 conda --version 2、查看当前已有虚拟环境 conda env list 3、创建新环境 conda create -n classify python3.9 创建一个叫做classify的虚拟环境&#xff0c;其中python等于3.9 4、进入虚拟环境 activate classify 5、安装包 接下来…

【数据结构】四、串

目录 一、定义 二、表示与实现 定长顺序存储 堆分配存储 链式存储 三、BF算法 四、KMP算法 1.求next数组 方法一 方法二&#xff08;考试方法&#xff09; 2.KMP算法实现 方法一 方法二 3.nextval 4.时间复杂度 本节最重要的就是KMP算法&#xff0c;其他要求不高…

电脑怎么重装系统?跟着步骤轻松搞定!

电脑系统随着时间的推移可能会变得迟缓或出现其他问题&#xff0c;而重装系统是解决这些问题的有效方法之一。本文将介绍三种电脑怎么重装系统的方法&#xff0c;帮助您在不同情况下选择适合自己的方案&#xff0c;让电脑焕然一新。 方法1&#xff1a;使用系统自带的恢复选项 …