您的位置:首页 > 编程语言 > Java开发

java重试之Spring Retry

2018-02-01 19:47 609 查看

背景

问题 :

项目中调用第三方服务异常而引起自己的某块业务没有正常进行,想通过重试调用几次第三方服务来降低出错率。

解决:

首先想到的是异常捕获,通过线程休眠来达到目的,当然简单的这么处理肯定是可以的。

可是我的第三方服务有点多,这么写我很累。。。

所以想着有什么简便的方式,看着看着就找到了spring-retry,多说无益,接下来就分享spring-retry的简单使用。

第一步、引入maven依赖

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>

第二步、添加@Retryable和@Recover注解

...
@Service
public class RemoteService {
@Retryable(value= {RpcException.class,RemoteAccessException.class},maxAttempts = 3,backoff = @Backoff(delay = 5000l,multiplier = 2))
public Object call() throws Exception {
System.out.println("do something...");
throw new RpcException("RPC调用异常");
}
@Recover
public Object recover(RpcExceptione) {
System.out.println(e.getMessage());
}
@Recover
public Object recover(RemoteAccessException e) {
System.out.println(e.getMessage());
}
}

@Retryable注解

被注解的方法发生异常时会重试
value:指定发生的异常进行重试 ,可以配置多个,那么对应的以某个异常为入参的recover方法也要加多个
include:和value一样,默认空,当exclude也为空时,所有异常都重试
exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
maxAttemps:重试次数,默认3
backoff:重试补偿机制,默认没有

@Backoff注解

delay:指定延迟后重试
multiplier:指定延迟的倍数,

比如delay=5000l,multiplier=2时,

第一次重试为5秒后,第二次为10秒,第三次为20秒

@Recover 注解

当重试到达指定次数时,被注解的方法将被回调,可以在该方法中进行日志处理。

需要注意:
发生的异常和入参类型一致时才会回调,本人调试的时候就是踩了这个坑 老是报 Cannot locate recovery method;

第三步、SpringBoot方式启动容器、测试

添加@EnableRetry注解,启用重试功能

@SpringBootApplication
@EnableRetry
public class Application {
public static void main(String[] args) throws Exception {
ApplicationContext annotationContext = new AnnotationConfigApplicationContext("hello");
RemoteService remoteService = annotationContext.getBean("remoteService", RemoteService.class);
remoteService.call();
}
}

但是你如果不是使用springBoot 那么 applicationContext.xml 增加如下配置 等价增加@EnableRetry注解

<context:annotation-config/>
<aop:aspectj-autoproxy/>
<bean class="org.springframework.retry.annotation.RetryConfiguration" /><!--retry 初始化 -->

最后要提的一点就是记得在日志中把debug打开哦……

接下来你就可以开心的在项目中试一下水啦!保证你“乐不思蜀“!

参考官方文档:
spring-retry
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息