Spring-Retry 重试机制小计
在实际工作中,重处理是一个非常常见的场景,比如:
发送消息失败。
调用远程服务失败。
争抢锁失败。
这些错误可能是因为网络波动造成的,等待过后重处理就能成功。通常来说,会用try/catch,while循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。
1.POM依赖
基于AOP实现,因此还需引入aop相关的依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.启用@Retryable
@EnableRetry
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
3.在方法上添加@Retryable
1.创建测试controller
@RestController
public class TestRetryController {
@Resource
private TestRetryService testRetryService;
@RequestMapping(value = "/test")
public int test(int code) throws Exception {
return testRetryService.testRetry(code);
}
}
2.创建service接口
public interface TestRetryService {
int testRetry(int code) throws Exception;
}
3.创建service实现类并添加@Retryable
@Service
public class TestRetryServiceImpl implements TestRetryService {
/**
* value:抛出指定异常才会重试
* include:和value一样,默认为空,当exclude也为空时,默认所有异常
* exclude:指定不处理的异常
* maxAttempts:最大重试次数,默认3次
* backoff:重试等待策略,
* 默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000; 以毫秒为单位的延迟(默认 1000)
* multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
* @param code
* @return
* @throws Exception
*/
@Override
@Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public int testRetry(int code) throws Exception{
System.out.println("test被调用,时间:"+ LocalTime.now());
if (code==0){
throw new Exception("情况不对头!");
}
System.out.println("test被调用,情况对头了!");
return 200;
}
/**
* Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。
* 如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。
* 可以看到传参里面写的是 Exception e,这个是作为回调的接头暗号(重试次数用完了,还是失败,我们抛出这个Exception e通知触发这个回调方法)。
* 注意事项:
* 方法的返回值必须与@Retryable方法一致
* 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
* 该回调方法与重试方法写在同一个实现类里面
*
* 由于是基于AOP实现,所以不支持类里自调用方法
* 如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void
* 方法内不能使用try catch,只能往外抛异常
* @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。
* @param e
* @param code
* @return
*/
@Recover
public int recover(Exception e, int code){
System.out.println("回调方法执行!!!!");
//记日志到数据库 或者调用其余的方法
System.out.println("异常信息:"+e.getMessage());
return 400;
}
}
来简单解释一下注解中几个参数的含义:
value:抛出指定异常才会重试
include:和value一样,默认为空,当exclude也为空时,默认所有异常
exclude:指定不处理的异常
maxAttempts:最大重试次数,默认3次
backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000(单位毫秒),我们设置为2000;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
当重试耗尽时还是失败,会出现什么情况呢?
当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。
@Recover
public int recover(Exception e, int code){
System.out.println("回调方法执行!!!!");
//记日志到数据库 或者调用其余的方法
System.out.println("异常信息:"+e.getMessage());
return 400;
}
4.测试效果
这里我们传入的code=0因此走异常的分支,由于我们添加@Retryable注解并设置了相关的参数,程序会按照配置进行重试,重试都失败之后会调用@Recover修饰的方法,最终返回400给浏览器
————————————————
版权声明:本文为CSDN博主「llp1110」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44981526/article/details/125657331
————————————————
原文链接:https://blog.csdn.net/qq_44981526/article/details/125657331
Spring-Retry 重试机制小计的更多相关文章
- spring retry 重试机制完整例子
public static Boolean vpmsRetryCoupon(final String userId) { // 构建重试模板实例 RetryTemplate retryTemplate ...
- 自己动手实践 spring retry 重试框架
前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...
- Spring Cloud重试机制与各组件的重试总结
SpringCloud重试机制配置 首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例. ? 1 2 3 4 5 6 7 8 @Bean @Lo ...
- Java之Retry重试机制详解
应用中需要实现一个功能: 需要将数据上传到远程存储服务,同时在返回处理成功情况下做其他操作.这个功能不复杂,分为两个步骤:第一步调用远程的Rest服务上传数据后对返回的结果进行处理:第二步拿到第一步结 ...
- Spring Retry 重试
重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...
- Guava Retry重试机制
1.添加pom依赖 <dependency> <groupId>com.github.rholder</groupId> <artifactId>gua ...
- spring boot常用注解小计
@Async 需要执行异步方法时,在方法上加上@Async之后,底层使用多线程技术 .启动类上需要加上 @EnableAsync 注意:异步执行方法,不能与引用方法同在一个类里 @Transactio ...
- 012 spring retry重试原理的解析
有点复杂,在后续的章节,将会对其中涉及到的知识点,再分章节进行说明. 1.程序结构 2.@Retryable package com.jun.web.annotation.theory; import ...
- springboot 整合retry(重试机制)
当我们调用一个接口可能由于网络等原因造成第一次失败,再去尝试就成功了,这就是重试机制,spring支持重试机制,并且在Spring Cloud中可以与Hystaix结合使用,可以避免访问到已经不正常的 ...
- JAVA重试机制多种方式深入浅出
重试机制在分布式系统中,或者调用外部接口中,都是十分重要的. 重试机制可以保护系统减少因网络波动.依赖服务短暂性不可用带来的影响,让系统能更稳定的运行的一种保护机制. 为了方便说明,先假设我们想要进行 ...
随机推荐
- 关于HarmonyOS NEXT中的模块化开发
今天不写页面和动画,斗胆给大家讲一讲软件工程. 软件工程讲究高内聚低耦合,意思就是把整个工程按照分工不同分成不同的模块,每一个模块紧密联系又互不影响.就像一座摩天大楼,它里面的电路网非常庞大和复杂,它 ...
- 在鸿蒙Next中开发一个月历组件
最近一直在出差,工作繁忙,很久没有时间更新文章了,连华为开发者大会也错过了.今天周末,忙里偷闲给大家分享一个鸿蒙月历组件. 这样的组件大家在工作中应该经常会遇到,而鸿蒙又没有提供一个这样的系统组件,今 ...
- Winform C#多显示器窗口控制详解
写Winform程序的时候,有将一个窗口放置到特定的显示器,并且全屏的需求.于是借此机会,好好研究了一番这个Screen类[1],总结了一些方法. Windows的窗口逻辑 首先我们需要知道窗口定位的 ...
- Asp.net core中HttpResponse常用属性及Status code
在ASP.NET Core中,HttpResponse 表示HTTP响应,其中包括一些常用的属性和方法,用于设置HTTP响应的各种属性.HTTP响应通常由一个HTTP状态码,HTTP头(headers ...
- 极简版闹钟(java)
package javaBasic; import java.awt.Toolkit; import java.awt.event.*; import java.text.SimpleDateForm ...
- React-Native开发鸿蒙NEXT-蓝牙信标读取
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...
- Java 枚举类的简单介绍
综述 enum 的全称为 enumeration, 是Java1.5引入的新特性,通过关键字enum来定义枚举类.它是一种特殊类,和普通类一样可以使用构造器.定义成员变量和方法,也能实现一个或多个 ...
- Linux系统通过firewall限制或开放端口
一.查看防火墙状态 systemctl status firewalld 开启防火墙并设置开机自启 systemctl start firewalld systemctl enable firewal ...
- 工程师都喜欢的一款自动生成网格的仿真软件——Hyperworks到底好不好用?
HyperWorks是一款广泛应用于工程仿真和优化的软件平台,其中包括了许多强大的工具和功能.其中的网格自动生成工具是其重要组成部分之一,对于工程仿真和优化来说具有重要的意义.那么,HyperWork ...
- Elastic学习之旅 (5) 倒排索引和Analyzer分词
大家好,我是Edison. 上一篇:ES文档的CRUD操作 重要概念1:倒排索引 在学习ES时,倒排索引是一个非常重要的概念.要了解倒排索引,就得先知道什么是正排索引.举个简单的例子,书籍的目录页(从 ...