Spring Retry 重试( 二 )


文章插图

Spring Retry 重试

文章插图

Spring Retry 重试

文章插图

Spring Retry 重试

文章插图
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. Listeners
public 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 注解,还可以指定任意数量的重试监听器 。

经验总结扩展阅读