java重试之Spring Retry

背景

问题 :
项目中调用第三方服务异常而引起自己的某块业务没有正常进行,想通过重试调用几次第三方服务来降低出错率。
解决:
首先想到的是异常捕获,通过线程休眠来达到目的,当然简单的这么处理肯定是可以的。
可是我的第三方服务有点多,这么写我很累。。。
所以想着有什么简便的方式,看着看着就找到了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

猜你喜欢

转载自my.oschina.net/nyp/blog/1617061