@Retryable注解的使用
@Retryable
前言
在实际工作中,重处理是一个非常常见的场景,比如:
- 发送消息失败。
- 调用远程服务失败。
- 争抢锁失败。
这些错误可能是因为网络波动造成的,等待过后重处理就能成功。通常来说,会用try/catch,while循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。
一、@Retryable是什么?
spring系列的spring-retry是另一个实用程序模块,可以帮助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有配置都是基于简单注释的。
二、使用步骤
1.POM依赖
  <!-- 因为是基于AOP实现的 所以引入AOP依赖 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
  </dependency>
 <dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
 </dependency>
2.启用@Retryable
@EnableRetry
@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication .class, args);
    }
}
3.在方法上添加@Retryable
@Service
public class TestRetryServiceImpl implements TestRetryService {
    @Override
    @Retryable(value = Exception.class,maxAttempts = 10,backoff = @Backoff(delay = 2000,multiplier = 1.5))
    public int testRetry(int code, String userName, List<String> list) throws Exception{
        System.out.println("testRetry被调用,时间:"+LocalTime.now());
          if (code==0){
              throw new Exception("发生错误!!!");
          }
        System.out.println("testRetry被调用,成功!!!");
        return 200;
    }
}
来简单解释一下注解中几个参数的含义:
- value:抛出指定异常才会重试
- include:和value一样,默认为空,当exclude也为空时,默认所有异常
- exclude:指定不处理的异常
- maxAttempts:最大重试次数,默认3次
- backoff:重试等待策略,默认使用- @Backoff,- @Backoff的value默认为1000L,我们设置为2000L;- multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把- multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
当重试耗尽时还是失败,会出现什么情况呢?
当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即。Spring-Retry还提供了@Recover注解,用于@Retryable`重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。
4.@Recover
@Recover
public int recover(Exception e, int code, String userName, List<String> list){
   System.out.println("回调方法执行!!!!");
   //参数的顺序要和上方方法的顺序一致,否则会出现参数类型不匹配
   System.out.println(code);
   System.out.println(userName);
   System.out.println(list);
   //记日志到数据库 或者调用其余的方法
   return 400;
}
可以看到传参里面写的是 Exception e,这个是作为回调的接头暗号(重试次数用完了,还是失败,我们抛出这个Exception e通知触发这个回调方法)。对于@Recover注解的方法,需要特别注意的是:
- 方法的返回值必须与@Retryable方法一致
- 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
- 该回调方法与重试方法写在同一个实现类里面
5. 注意事项
- 由于是基于AOP实现,所以不支持类里自调用方法
- 如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void
- 方法内不能使用try catch,只能往外抛异常
- @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是- @Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。
@Retryable注解的使用的更多相关文章
- 扒一扒@Retryable注解,很优雅,有点意思!
		你好呀,我是歪歪. 前几天我 Review 代码的时候发现项目里面有一坨逻辑写的非常的不好,一眼望去简直就是丑陋之极. 我都不知道为什么会有这样的代码存在项目里面,于是我看了一眼提交记录准备叫对应的同 ... 
- 关于Spring注解@Async引发其他注解失效
		概述 在前面一篇文章中,介绍,在一个Bean中注入自己,如果有@Async和@Transaction,如果使用@Autowire注入自身,会报循环依赖,如果使用BeanFactoryAware注入自己 ... 
- 用spring-retry注解自动触发重试方法
		原文地址:https://www.jianshu.com/p/ee02d6125113 需求背景: 有些时候我们再调用一些第三方服务的时候,从第三方那边拉数据. 但是第三方服务不是100%稳定的,有些 ... 
- 一个注解@Recover搞定丑陋的循环重试代码
		使用背景 在实际项目中其中一部分逻辑可能会因为调用了外部服务或者等待锁等情况下出现不可预料的异常,在这个时候我们可能需要对调用这部分逻辑进行重试,代码里面主要就是使用for循环写一大坨重试的逻辑,各种 ... 
- Spring异步调用原理及SpringAop拦截器链原理
		一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ... 
- springboot retry
		try/catch,while 循环或者定时任务 这样看起来 好 low sping boot retry , 这样代码更简洁 eg: @Retryable(value= {RemoteAcce ... 
- Spring retry实践
		在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ... 
- Spring异常重试框架Spring Retry
		Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ... 
- 异常重试框架Spring Retry实践
		前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ... 
- springboot 整合retry(重试机制)
		当我们调用一个接口可能由于网络等原因造成第一次失败,再去尝试就成功了,这就是重试机制,spring支持重试机制,并且在Spring Cloud中可以与Hystaix结合使用,可以避免访问到已经不正常的 ... 
随机推荐
- 第九十五篇:vue-router的导航守卫
			好家伙,考完期末考了. 恢复博客更新 1.什么是导航守卫? "导航"表示路由正在发生变化 设置导航,就在切换过程中进行限制 "守卫"就好理解了 盯着你,不然 ... 
- C语言:多功能计算器程序说明书
			好家伙,3000字终于写完了 一.题目:多功能科学计算器 二.内容: (1)概述或引言 开发环境为Visual C++ 目前已实现的功能: (1)解二元一次方程.一元二次方程 (2)进行矩阵相加.相减 ... 
- pathlib路径问题
			下面是我的文件框架 app ------ file1---- .py1 file2---- .py2 config.py 我在config文件中设置了变量参数 BASE_DIR = pathlib.P ... 
- Linux常用基础命令一
			一.目录操作 进入路径 cd [目录地址] 切换回主目录 cd 返回上一个路径 cd - 打印当前路径 pwd 列出目录下文件 ls ---查看只包含非隐藏文件 ls -a -----查看目录下所有文 ... 
- Cluster table 与性能
			用户数据行存储在文件系统中的堆文件中,而这些行以不确定的顺序存储.如果表最初以插入/复制的顺序加载,那么以后的插入.更新和删除将导致在堆文件中以不可预测的顺序添加行.创建索引创建一个指向堆行的辅助文件 ... 
- sedona(Geospark)读取csv
			package com.grady.sedona import org.apache.sedona.sql.utils.SedonaSQLRegistrator import org.apache.s ... 
- 如何在 Jenkins CI/CD 流水线中保护密钥?
			CI/CD 流水线是 DevOps 团队软件交付过程的基本组成部分.该流水线利用自动化和持续监控来实现软件的无缝交付.通过持续自动化,确保 CI/CD 流水线每一步的安全性非常重要.在流水线的各个阶段 ... 
- Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架
			Memlab 是一款 E2E 测试和分析框架,用于发现 JavaScript 内存泄漏和优化机会. Memlab 是 JavaScript 的内存测试框架.它支持定义一个测试场景(使用 Puppete ... 
- 在Winform开发中,我们使用的几种下拉列表展示字典数据的方式
			在Winform开发中中,我们为了方便客户选择,往往使用系统的字典数据选择,毕竟选择总比输入来的快捷.统一,一般我们都会简单封装一下,以便方便对控件的字典值进行展示处理,本篇随笔介绍DevExpres ... 
- Beats:Beats在Kibana中的集中管理
			我们可以通过在命令行中对我们的Beats进行管理,比如我们可以启动metric几个模块,我们可以通过如下的命令来执行: ./metricbeat modules enable apache mysql ... 
