Spring Retry
最近组内准备将项目中原有的重试功能抽取出来重构为一个重试平台,由于对重试的功能要求比较高,采用了不少中间件和框架(jimdb,jproxy, Elastic-Job ,JMQ,Hbase, Disruptor ),而且重写了 BlockingQueue,平台构架也比较复杂,在设计重试平台前,也调研过一些重试的开源框架,Spring Retry映入了眼帘,虽然最后没有采用它,但是还是想在此处介绍一下它。
在分布式系统中,为了保证数据分布式事务的强一致性,大家在调用RPC接口或者发送MQ时,针对可能会出现网络抖动请求超时情况采取一下重试操作。大家用的最多的重试方式就是MQ了,但是如果你的项目中没有引入MQ,那就不方便了,本文主要介绍一下如何使用Spring Retry实现重试操作。
1、引入Spring Retry依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
2、在启动入口加入重试配置
添加@EnableRetry注解
@SpringBootApplication
@EnableRetry
public class RetryApplication {
public static void main(String[] args) throws Exception{
SpringApplication.run(RetryApplication.class, args);
}
}
3、编写测试service
@Service
public class RetryService {
@Retryable(value= {RemoteAccessException.class},maxAttempts = 5,backoff = @Backoff(delay = 5000l,multiplier = 1))
public void retryTest() throws Exception {
System.out.println("do something...");
throw new RemoteAccessException("RemoteAccessException....");
}
@Recover
public void recover(RemoteAccessException e) {
System.out.println(e.getMessage());
System.out.println("recover....");
}
}
4、测试service
@Configuration
@EnableRetry
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class RetryServiceMain {
@Bean
public RetryService retryService(){
return new RetryService();
}
public static void main(String[] args) throws Exception{
final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(RetryServiceMain.class);
final RetryService retryService = applicationContext.getBean(RetryService.class);
retryService.retryTest();
}
}
Run这个main方法,控制台会打印如下内容
16:12:28.932 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'retryService'
16:12:28.954 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=0
do something...
16:12:28.973 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:12:33.974 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=1
16:12:33.974 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=1
do something...
16:12:33.974 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:12:38.974 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=2
16:12:38.974 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=2
do something...
16:12:38.974 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:12:43.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=3
16:12:43.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=3
do something...
16:12:43.975 [main] DEBUG org.springframework.retry.backoff.ExponentialBackOffPolicy - Sleeping for 5000
16:12:48.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=4
16:12:48.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=4
do something...
16:12:48.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=5
16:12:48.975 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry failed last attempt: count=5
RemoteAccessException....
recover....
可见方法重试了五次,每次间隔了5秒,第五次失败后执行了recover方法。
介绍一下几个注解
- @EnableRetry能否重试。当proxyTargetClass属性为true时,使用CGLIB代理。默认使用标准JAVA注解。在spring Boot中此参数写在程序入口即可。
- @Retryable 标注此注解的方法在发生异常时会进行重试
value:指定处理的异常类
include:指定处理的异常类和value一样,默认为空,当exclude也为空时,默认所有异常
exclude:指定异常不处理,默认空,当include也为空时,默认所有异常
maxAttempts:最大重试次数。默认3次
backoff: 重试等待策略。默认使用@Backoff注解
- @Backoff 重试等待策略
不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms
设置delay,使用FixedBackOffPolicy(指定等待时间),重试等待填写的时间
设置delay和maxDealy时,重试等待在这两个值之间均态分布
设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现 ),multiplier即指定延迟倍数,比如delay=5000l,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒……
@Recover 用于@Retryable重试失败后处理方法,此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。
spring-retry项目地址:https://github.com/spring-projects/spring-retry
Spring Retry的更多相关文章
- Spring retry基本使用
Spring retry基本使用 背景介绍 在实际工作过程中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络 波动出现超时而采取重试手段 ...
- 自己动手实践 spring retry 重试框架
前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...
- Spring retry实践
在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ...
- Spring异常重试框架Spring Retry
Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...
- 【spring】spring retry介绍
一.为什么需要重试? 我们知道只要是网络请求都有失败的情况,这个时候增加retry机制是必要的.而spring全家桶中就有这么一套机制. 二.spring retry spring系列的spring ...
- 异常重试框架Spring Retry实践
前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ...
- Spring框架中一个有用的小组件:Spring Retry
1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...
- Spring Retry 在SpringBoot 中的应用
Spring Boot中使用Spring-Retry重试框架 Spring Retry提供了自动重新调用失败的操作的功能.这在错误可能是暂时的(例如瞬时网络故障)的情况下很有用. 从2.2.0版本开始 ...
- Spring Retry 重试
重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...
随机推荐
- Date类为什么设计为可变的,而不是像String一样?
首先,不得不承认,这确实是类库设计的一个错误,所以"为什么"进行了这个错误设计并没有意义.但没有事物一诞生就是完美的,我们的Java只是反应的慢了一点,再慢了一点. 更何况,Dat ...
- bzoj3295 动态逆序对
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...
- java日期比较例子等...
数据库中employ表,入职日期,今天日期: 测试代码: package javademo; import java.sql.Connection; import java.sql.DriverMan ...
- java web程序 jdbc连接数据库错误排查方法
学习jsp.我遇到了麻烦,我总是看不懂500错误,因为每次都显示整个页面的错误,都是英文 我看不懂,后来,把他弄烦了,我也烦了,比起学习java.那个异常可以很简单的就知道.现在解决 了第一个问题,5 ...
- Bootstrap:教程、简介、环境安装
ylbtech-Bootstrap:教程.简介.环境安装 1. Bootstrap 教程返回顶部 1. Bootstrap 教程 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.B ...
- [原]DataGridView 回车不换行代码 AND 编辑时的字符控制
// 让 dataGridView1 在遇到回车时不响应 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { ...
- MySQL工具 Navicat
F6打开命令行窗口 ctrl+shift+r 运行选中语句 #不过不建议使用,因为ctrl+r是执行当前所有语句,如果语句当中有delete update 后果不堪设想
- 关于Linux DNS部分处理
如果不能ping 通外网地址进行解析的话进行如下处理
- gearman在虚拟机上运行没有自动开启的处理
几天来被gearman无响应的问题困扰,后来请教了大神解决.原因是gearman在虚拟机上运行不稳定,无法自动开启,需手动开始,输入图片的两行命令即开始.
- 2018ICPC网络赛(徐州站)A题题解
一.题目链接 https://nanti.jisuanke.com/t/31453 二.题意 给定$N$个位置,$2^k$种颜色,让你去涂色,条件是相邻的两种颜色类型异或值的二进制表示不全为$1$(以 ...