文档章节

在Spring Boot中使用Spring Retry

老虎是个蛋蛋
 老虎是个蛋蛋
发布于 2017/01/18 16:41
字数 952
阅读 5029
收藏 41

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

© 著作权归作者所有

老虎是个蛋蛋
粉丝 173
博文 31
码字总数 40085
作品 0
朝阳
高级程序员
私信 提问
加载中

评论(1)

阿卡
阿卡
666写多线程也可以试试
第二章——Spring Boot启动器与依赖管理

强烈推荐选择支持依赖管理和可以发布到“Maven中央”仓库的构建系统。推荐使用Maven或Gradle。Spring Boot可以使用其他构建系统(例如,Ant),但支持得并不是很好。 1 依赖管理 Spring Boo...

Leech
2018/02/04
0
0
Spring Boot 为什么这么火?

没错 Spring Boot 越来越火了,而且火的超过了我的预期,作为一名行走一线的 Java 程序员,你可能在各个方面感受到了 Spring Boot 的火。 Spring Boot 的火 技术社区 Spring Boot 的文章越来...

ityouknow
06/03
0
0
Spring Boot 2.0 的快速入门(图文教程)

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! Spring Boot 2.0 的快速入门(图文教程) 大家都知道,Spring Framework 是 Java/S...

01/04
0
0
Spring Boot 整合 MyBatis

最近项目原因可能会继续开始使用MyBatis,已经习惯于spring-data的风格,再回头看xml的映射配置总觉得不是特别舒服,接口定义与映射离散在不同文件中,使得阅读起来并不是特别方便。 Spring...

中关村的老男孩
06/24
67
0
​Spring Boot 2.0 同步至 Maven 仓库出错,已撤回……

Spring Boot 2.0 目前已在 GitHub 上发布了 v2.0.0.RELEASE 版本(https://github.com/spring-projects/spring-boot/releases/tag/v2.0.0.RELEASE)。 不过还没同步至 Maven 中央仓库,请保持关......

凝小紫
2018/03/01
9.8K
54

没有更多内容

加载失败,请刷新页面

加载更多

MySQL8.0.17 - Multi-Valued Indexes 简述

本文主要简单介绍下8.0.17新引入的功能multi-valued index, 顾名思义,索引上对于同一个Primary key, 可以建立多个二级索引项,实际上已经对array类型的基础功能做了支持 (感觉官方未来一定...

阿里云官方博客
19分钟前
2
0
make4.1降级 make-3.81、2错误

在编译 make-3.82 的时候出现如下错误提示 glob/glob.c:xxx: undefined reference to `__alloca'` 修改 /glob/glob.c // #if !defined __alloca && !defined __GNU_LIBRARY__ # ifdef __GNUC......

Domineering
20分钟前
1
0
Rainbond集群的安装和运维的原理

本文将解读Rainbond集群的安装和运维的原理,使用户基本了解Rainbond的安装机制和运维重点,便于用户搭建大型Rainbond集群。 1.Rainbond集群节点概述 1.1 节点分类 属性 类型 说明 manage 管...

好雨云帮
32分钟前
3
0
好程序员大数据学习路线分享UDF函数

1.为什么需要UDF? 1)、因为内部函数没法满足需求。 2)、hive它本身就是一个灵活框架,允许用自定义模块功能,如可以自定义UDF、serde、输入输出等。 2.UDF是什么? UDF:user difine fun...

好程序员官方
34分钟前
3
0
Groovy中 Base64 URL和文件名安全编码

Base64 URL和文件名安全编码 Groovy支持Base64编码很长一段时间。 从Groovy 2.5.0开始,我们还可以使用Base64 URL和Filename Safe编码来使用encodeBase64Url方法对字节数组进行编码。 结果是...

白石
37分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部