文章插图

文章插图

文章插图

文章插图
1. 用法
声明式
@Configuration@EnableRetrypublic class Application {}@Serviceclass Service {@Retryable(RemoteAccessException.class)public void service() {// ... do something}@Recoverpublic void recover(RemoteAccessException e) {// ... panic}}
命令式RetryTemplate template = RetryTemplate.builder().maxAttempts(3).fixedBackoff(1000).retryOn(RemoteAccessException.class).build();template.execute(ctx -> {// ... do something});
2. RetryTemplate为了自动重试,Spring Retry 提供了 RetryOperations 重试操作策略
public interface RetryOperations {<T> T execute(RetryCallback<T> retryCallback) throws Exception;<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback)throws Exception;<T> T execute(RetryCallback<T> retryCallback, RetryState retryState)throws Exception, ExhaustedRetryException;<T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback,RetryState retryState) throws Exception;}
基本回调是一个简单的接口,允许插入一些要重试的业务逻辑:public interface RetryCallback<T> {T doWithRetry(RetryContext context) throws Throwable;}
回调函数被尝试,如果失败(通过抛出异常),它将被重试,直到成功或实现决定中止 。RetryOperations最简单的通用实现是RetryTemplate
RetryTemplate template = new RetryTemplate();TimeoutRetryPolicy policy = new TimeoutRetryPolicy();policy.setTimeout(30000L);template.setRetryPolicy(policy);Foo result = template.execute(new RetryCallback<Foo>() {public Foo doWithRetry(RetryContext context) {// Do stuff that might fail, e.g. webservice operationreturn result;}});
从Spring Retry 1.3开始,RetryTemplate支持流式配置:RetryTemplate.builder().maxAttempts(10).exponentialBackoff(100, 2, 10000).retryOn(IOException.class).traversingCauses().build();RetryTemplate.builder().fixedBackoff(10).withinMillis(3000).build();RetryTemplate.builder().infiniteRetry().retryOn(IOException.class).uniformRandomBackoff(1000, 3000).build();
3. RecoveryCallback当重试耗尽时,RetryOperations可以将控制传递给不同的回调:RecoveryCallback 。
Foo foo = template.execute(new RetryCallback<Foo>() {public Foo doWithRetry(RetryContext context) {// business logic here},new RecoveryCallback<Foo>() {Foo recover(RetryContext context) throws Exception {// recover logic here}});
4. Listenerspublic interface RetryListener {void open(RetryContext context, RetryCallback<T> callback);void onSuccess(RetryContext context, T result);void onError(RetryContext context, RetryCallback<T> callback, Throwable e);void close(RetryContext context, RetryCallback<T> callback, Throwable e);}
在最简单的情况下,open和close回调在整个重试之前和之后,onSuccess和onError应用于个别的RetryCallback调用,onSuccess方法在成功调用回调之后被调用 。5. 声明式重试
有时,你希望在每次业务处理发生时都重试一些业务处理 。这方面的典型例子是远程服务调用 。Spring Retry提供了一个AOP拦截器,它将方法调用封装在RetryOperations实例中 。RetryOperationsInterceptor执行被拦截的方法,并根据提供的RepeatTemplate中的RetryPolicy在失败时重试 。
你可以在 @Configuration 类上添加一个 @EnableRetry 注解,并且在你想要进行重试的方法(或者类)上添加 @Retryable 注解,还可以指定任意数量的重试监听器 。
经验总结扩展阅读
- SpringBoot自定义注解+异步+观察者模式实现业务日志保存
- 装配 SpringBoot自动配置流程
- 四十七 SpringCloud微服务实战——搭建企业级开发框架:【移动开发】整合uni-app搭建移动端快速开发框架-添加Axios并实现登录功能
- SpringCloud怎么迈向云原生?
- Filter Spring中过滤器和拦截器(Interceptor)的区别和联系
- 二 SpringCloud - Eureka注册中心,feign远程调用,hystrix降级和熔断
- 二 【SSM】学习笔记——SpringMVC入门
- 四十六 SpringCloud微服务实战——搭建企业级开发框架:【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建
- Springboot 一行代码实现文件上传 20个平台!少写代码到极致
- SpringBoot内置工具类,告别瞎写工具类了