spring retry是从spring batch独立出来的一个功能,主要实现了重试和熔断。
重试策略:
NeverRetryPolicy:只调用RetryCallback一次,不重试
SimpleRetryPolicy:重试n次,默认3次,也是RetryTemplate模板默认的策略。很常用
ExceptionClassifierRetryPolicy:可以根据不同的异常,执行不同的重试策略,很常用
TimeoutRetryPolicy:在n毫秒内不断进行重试,超过这个时间后停止重试
CircuitBreakerRetryPolicy:熔断功能的重试
CompositeRetryPolicy:将不同的策略组合起来,有悲观组合和乐观组合。悲观默认重试,有不重试的策略则不重试。乐观默认不重试,有需要重试的策略则重试
AlwaysRetryPolicy:无限重试,最好不要用
退避策略:每次重试是立即重试还是等待一段时间后重试
NoBackOffPolicy:不回避
FixedBackOffPolicy:n毫秒退避后再进行重试,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒
UniformRandomBackOffPolicy:随机选择一个[n,m](如20ms,40ms)回避时间回避后,然后再重试,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在[minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒
ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier
ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数可以实现随机乘数回退
无状态重试是指重试在一个线程上下文中完成的重试,反之不在一个线程上下文完成重试的就是有状态重试。需要有状态重试的情况通常有两种:事务回滚和熔断。
主要的依赖包:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency>
范例:
public void retry1() throws Exception { RetryTemplate retryTemplate = new RetryTemplate(); //重试策略 SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); retryPolicy.setMaxAttempts(3); //最多重试3次 // TimeoutRetryPolicy retryPolicy = new TimeoutRetryPolicy(); // retryPolicy.setTimeout(5000L); //超时重试:在指定时间内可以不断重试 //退避策略 FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy(); fixedBackOffPolicy.setBackOffPeriod(500); //间隔1000毫秒 retryTemplate.setRetryPolicy(retryPolicy); retryTemplate.setBackOffPolicy(fixedBackOffPolicy); //重试操作 final RetryCallback<Boolean, Exception> retryCallback = new RetryCallback<Boolean, Exception>() { @Override public Boolean doWithRetry(RetryContext retryContext) throws Exception { System.out.println(String.format("retry count: %s", retryContext.getRetryCount()+1)); throwError(retryContext.getRetryCount()+1); return true; } }; //重试失败后执行兜底回调 final RecoveryCallback<Boolean> recoveryCallback = new RecoveryCallback<Boolean>() { @Override public Boolean recover(RetryContext retryContext) throws Exception { System.out.println(String.format("after retry: %s, recovery method called!", retryContext.getRetryCount()+1)); return false; } }; Boolean result = retryTemplate.execute(retryCallback, recoveryCallback); System.out.println(String.format("execute result: %s", result)); } private void throwError(int retryCount) throws Exception { if(retryCount < 20){ throw new Exception(""); } }
在Springboot环境下使用spring retry:
主要注解类:
@EnableRetry:启用重试机制,proxyTargetClass属性为true时(默认false)使用CGLIB代理
@Retryable:在需要被重试的方法上加上该注解类
maxAttempts 最大重试次数。默认3次
vaue 指定要重试的异常。默认为空
backoff 重试等待策略。默认使用@Backoff注解
include 指定处理的异常类。默认为空
exclude 指定不需要处理的异常。默认为空
@Backoff:重试回退策略(立即重试还是等待一会再重试)
delay 延迟重试的毫秒数
multiplier 延迟间隔时间的倍数
不设置参数时,默认使用FixedBackOffPolicy,重试等待1000ms
只设置delay()属性时,使用FixedBackOffPolicy,重试等待指定的毫秒数
当设置delay()和maxDealy()属性时,重试等待在这两个值之间均态分布
使用delay(),maxDealy()和multiplier()属性时,使用ExponentialBackOffPolicy
当设置multiplier()属性不等于0时,同时也设置了random()属性时,使用ExponentialRandomBackOffPolicy
@Recover: 用于方法。
用于@Retryable失败时的“兜底”处理方法
@CircuitBreaker:用于方法,实现熔断模式。
include 指定处理的异常类。默认为空
exclude指定不需要处理的异常。默认为空
vaue指定要重试的异常。默认为空
maxAttempts 最大重试次数。默认3次
openTimeout 配置熔断器打开的超时时间,默认5s,当超过openTimeout之后熔断器电路变成半打开状态(只要有一次重试成功,则闭合电路)
resetTimeout 配置熔断器重新闭合的超时时间,默认20s,超过这个时间断路器关闭
定义服务类:
/** * 使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效 * @Retryable 跟 @Recover 标注的方法,返回值必须相同。 * 使用了@Retryable的方法里面不能使用try...catch包裹,要在方法上抛出异常,不然不会触发 */ @Service public class RemoteService { /** * 调用该方法过程中发生RemoteAccessException异常时触发重试机制,重试次数达到指定值后,触发@Recover标注的方法 */ @Retryable(value=RemoteAccessException.class, maxAttempts=3, backoff=@Backoff(delay=500, multiplier=1.5)) public void call() throws Exception { throw new RemoteAccessException("invoke RemoteService.call() error"); } /** * 退避方法 */ @Recover public void recover(RemoteAccessException ex) { System.out.println(ex.toString()); } /** * Exception异常没有对应的退避方法 */ @Retryable(value=Exception.class, maxAttempts=3) public boolean pay(int num) throws Exception { System.out.println(LocalDateTime.now().toString()); if(num < 0){ throw new Exception("num must be greater than 0"); } return true; } }
在启动类引用服务类进行测试:
@SpringBootApplication() @RestController @EnableRetry //启用重试机制 public class Main{ @Autowired private RemoteService remoteService; public static void main(String[] args){ SpringApplication.run(Main.class, args); } @GetMapping("/index") public String index(){ try { remoteService.call(); remoteService.pay(-1); } catch (Exception ex) { System.out.println(ex.toString()); } return LocalDateTime.now().toString(); } }
相关推荐
压缩包包含着springboot项目retry,项目中演示了使用spring-retry传统的方式以及注解的方式使用重试的案例,也有guava-retry的使用案例,以及两者的区别
在业务场景中 , 有时候会遇到异常后需要重复尝试的操作 , 例如调用三方接口 , 发送邮件/短信 , 推送消息等等 . Spring 提供了Retry组件 , 很方便的解决了上述问题
Spring-Retry的使用非常直观。首先,你需要在项目中添加Spring-Retry的依赖。然后,你可以通过在需要重试的方法上添加`@Retryable`注解来声明这个方法在失败时应该被重试。你还可以指定重试的策略,比如最大重试次数...
spring-retry jar
spring-amqp,spring-retry,spring-rabbit
主要介绍了Spring boot使用spring retry重试机制的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。这篇文章主要介绍了详解重试框架Spring retry实践,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了详解Spring Retry实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Spring重试 使用spring-retry项目的例子
此项目为spring提供声明性重试支持。
主要介绍了spring-retry简单使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
本篇文章主要介绍了Spring重试支持Spring Retry的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
市面上开源的重试框架有很多,如Guava Retry、Spring Retry等都支持重试,但是他们都不支持任务的持久化,系统更新重启,重试任务就会丢失,这无法保证数据的一致性。传统的做法是写一个定时任务,定时补偿。但这样...
spring-retry-1.0.0.RELEASE.jar
目前有两个开源的类库spring retry and guava retry都支持编程式,spring retry更加融合spring的aop注解驱动,使用更加的方便。模拟异常场景为了实现demo,模拟了异常的场景异常调用...
适用于支付回调,多系统之间(需要自定义重试的场景)
Spring-retry 1.1.4重试功能.rar
spring-retry框架对于调用失败的情况下,重试操作工程示例。对应博客文章 https://blog.csdn.net/magi1201/article/details/115527022