Spring Retry 重试( 二 )

基本回调是一个简单的接口,允许插入一些要重试的业务逻辑:
public interface RetryCallback<T> {T doWithRetry(RetryContext context) throws Throwable;}回调函数被尝试,如果失败(通过抛出异常),它将被重试,直到成功或实现决定中止 。
【Spring Retry 重试】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 注解,还可以指定任意数量的重试监听器 。
@Configuration@EnableRetrypublic class Application {@Beanpublic Service service() {return new Service();}@Bean public RetryListener retryListener1() {return new RetryListener() {...}}@Bean public RetryListener retryListener2() {return new RetryListener() {...}}}@Serviceclass Service {@Retryable(RemoteAccessException.class)public service() {// ... do something}}可以使用 @Retryable 的属性类控制 RetryPolicy 和 BackoffPolicy
@Serviceclass Service {@Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))public service() {// ... do something}}如果希望在重试用尽时采用替代代码返回,则可以提供恢复方法 。方法应该声明在与@Retryable实例相同的类中,并标记为@Recover 。返回类型必须匹配@Retryable方法 。恢复方法的参数可以包括抛出的异常和(可选地)传递给原始可重试方法的参数(或者它们的部分列表,只要在需要的最后一个之前不省略任何参数) 。
@Serviceclass Service {@Retryable(RemoteAccessException.class)public void service(String str1, String str2) {// ... do something}@Recoverpublic void recover(RemoteAccessException e, String str1, String str2) {// ... error handling making use of original args if required}}若要解决可选择用于恢复的多个方法之间的冲突,可以显式指定恢复方法名称 。
@Serviceclass Service {@Retryable(recover = "service1Recover", value = https://www.huyubaike.com/biancheng/RemoteAccessException.class)public void service1(String str1, String str2) {// ... do something}@Retryable(recover ="service2Recover", value = https://www.huyubaike.com/biancheng/RemoteAccessException.class)public void service2(String str1, String str2) {// ... do something}@Recoverpublic void service1Recover(RemoteAccessException e, String str1, String str2) {// ... error handling making use of original args if required}@Recoverpublic void service2Recover(RemoteAccessException e, String str1, String str2) {// ... error handling making use of original args if required}}https://github.com/spring-projects/spring-retry

推荐阅读