最近组内准备将项目中原有的重试功能抽取出来重构为一个重试平台,由于对重试的功能要求比较高,采用了不少中间件和框架(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的更多相关文章

  1. Spring retry基本使用

    Spring retry基本使用 背景介绍 在实际工作过程中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络 波动出现超时而采取重试手段 ...

  2. 自己动手实践 spring retry 重试框架

    前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...

  3. Spring retry实践

    在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ...

  4. Spring异常重试框架Spring Retry

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  5. 【spring】spring retry介绍

    一.为什么需要重试? 我们知道只要是网络请求都有失败的情况,这个时候增加retry机制是必要的.而spring全家桶中就有这么一套机制. 二.spring retry spring系列的spring ...

  6. 异常重试框架Spring Retry实践

    前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ...

  7. Spring框架中一个有用的小组件:Spring Retry

    1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...

  8. Spring Retry 在SpringBoot 中的应用

    Spring Boot中使用Spring-Retry重试框架 Spring Retry提供了自动重新调用失败的操作的功能.这在错误可能是暂时的(例如瞬时网络故障)的情况下很有用. 从2.2.0版本开始 ...

  9. Spring Retry 重试

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...

随机推荐

  1. myeclipse修改编译器版本的方法 .

    今天在导入一个工程时,发现出现java.lang.UnsupportedClassVersionError: Bad version number in .class file异常,检查了一下我的my ...

  2. TextBox(只允许输入字母或者数字)——重写控件

    实现如下: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System ...

  3. 字符串拼接和dom回流

    以对象的角度分析  对象的两方面 属性和方法 研究对象,主要是研究对象的属性和方法 案例: <ul id="list"> <li></li> & ...

  4. laravel 5.3 ——路由(资源,别名)

    laravel的路由定义中,其中route:resoure(),可以直接定义类似restful风格的URL 例如:Route::resource('system/role','System\RoleC ...

  5. pig概述

    pig概述pig是一个用于并行计算的高级数据流语言和执行框架:类sql.文件处理框架:有一套和sql类似的执行语句,处理的对象是HDFS上文件.Pig的数据处理语言是数据流方式的,一步一步的进行处理: ...

  6. 普适注意力:用于机器翻译的2D卷积神经网络,显著优于编码器-解码器架构

    现有的当前最佳机器翻译系统都是基于编码器-解码器架构的,二者都有注意力机制,但现有的注意力机制建模能力有限.本文提出了一种替代方法,这种方法依赖于跨越两个序列的单个 2D 卷积神经网络.该网络的每一层 ...

  7. linux优化之全过程

    基于开放源代码的Linux给用户提供了这样一个平台:可以根据自己的软.硬件环境,定制自己的Linux应用环境.因此,根据每个用户不同的应用范围定制应用环境,可以将Linux系统的性能提升到新的高度. ...

  8. Solr Facet 搜索时,facet.missing = true 的真正含义

    Solr的WiKI原文是如下解释: facet.missing Set to "true" this param indicates that in addition to the ...

  9. css常用字体

    宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 PMingLiU 细明体 Ming ...

  10. redis入门之jedis

    jedis是redis官方首选的java客户端开发包 开源托管地址:https://github.com/xetorthio/jedis 下载地址,以及maven, 依赖参考: 下面来编写一段程序进行 ...