> 文章列表 > Spring Retry框架的使用教程

Spring Retry框架的使用教程

Spring Retry框架的使用教程

Spring Retry是Spring提供的重试机制,它支持注解方式进行配置,可以做到代码无浸入的重试操作。它的使用也很简单,我们先了解一下Spring Retry的基础概念。

一、基础概念:

String Retry支持普通方式使用和注解方式使用(下文中会展示写法)。我们重点说一下注解方式使用,这里主要设计到三个注解,具体如下:

  • @EnableRetry :添加在启动类上,表示开启重试。

  • @Retryable:添加在需要重试的方法上,该方法在发生异常时,会进行重试。

  • @Recover:用于@Retryable重试失败后的处理方法。

String Retry有7种重试策略,具体如下:

  • NeverRetryPolicy:只允许调用RetryCallback一次,不允许重试。

  • AlwaysRetryPolicy:允许无限重试,直到成功,此方式逻辑不当会导致死循环。

  • SimpleRetryPolicy:固定次数重试策略,默认重试最大次数为3次,RetryTemplate默认使用的策略。

  • TimeoutRetryPolicy:超时时间重试策略,默认超时时间为1秒,在指定的超时时间内允许重试。

  • ExceptionClassifierRetryPolicy:设置不同异常的重试策略,类似组合重试策略,区别在于这里只区分不同异常的重试。

  • CircuitBreakerRetryPolicy:有熔断功能的重试策略,需设置3个参数openTimeout、resetTimeout和delegate。

  • CompositeRetryPolicy:组合重试策略,有两种组合方式,乐观组合重试策略是指只要有一个策略允许即可以重试,悲观组合重试策略是指只要有一个策略不允许即可以重试,但不管哪种组合方式,组合中的每一个策略都会执行。

String Retry有5种重试回退策略,具体如下:

  • NoBackOffPolicy:无退避算法策略,每次重试时立即重试。

  • FixedBackOffPolicy:固定时间的退避策略,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒。

  • UniformRandomBackOffPolicy:随机时间退避策略,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在minBackOffPeriod、maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒。

  • ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即,下一次休眠时间为当前休眠时间multiplier。

  • ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数可以实现随机乘数回退。

二、注解方式使用:

想要使用String Retry,首先要引入架包,然后在启动类上加@EnableRetry注解,最后在需要重试的方法上加@Retryable注解,即可进行重试操作,具体代码如下(注意recover方法上注释,否则有可能不生效):

----- ----- 引入架包 ----- -----
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.1.5.RELEASE</version>
</dependency>----- ----- 具体代码 ----- -----/* 方式2* <p>* 1. RemoteAccessException的异常才重试* 2. @Backoff(delay = 2000L,multiplier = 2)) 表示第一次间隔2秒,以后都是次数的2倍,也就是第二次4秒,第三次6秒 @return*/@Retryable(value = {RemoteAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))public Boolean retry2(String param) {return RetryTask.task(param);}/* recover 机制:达到最大重试次数,或抛出了一个没有指定进行重试的异常,调用此方法* <p>* Tips:* 1. 返回值必须和被重试的函数返回值一致* 2. 参数中除了第一个是触发的异常外,后面的参数需要和被重试函数的参数列表一致* 3. @Recover注解与@Retryable注解在通过方法中 @param e* @param param* @return*/@Recoverpublic Boolean recover(Exception e, String param) {log.error("达到最大重试次数,或抛出了一个没有指定进行重试的异常:{},请求参数:{}", e, param);return false;}----- ----- 重试任务 ----- -----
public class RetryTask {/* 具体任务 @param param* @return*/public static Boolean task(String param) {int num = RandomUtils.nextInt(0, 9);log.info("请求参数:[{}],生成随机数:[{}]", param, num);if (num == 0) {log.info("模拟抛出参数异常");throw new IllegalArgumentException("参数异常");} else if (num == 1) {log.info("模拟执行成功");return true;} else if (num == 2) {log.info("模拟执行失败");return false;} else {log.info("模拟抛出特定异常");throw new RemoteAccessException("抛出远程访问异常");}}}

三、普通方式使用:

String Retry的普通方式的使用也很简单,具体如下:

    public Boolean retry1() {RetryTemplate retryTemplate = new RetryTemplate();// 设置重试回退操作策略,主要设置重试间隔时间FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();// 重试间隔时间ms,默认1000msbackOffPolicy.setBackOffPeriod(1000L);retryTemplate.setBackOffPolicy(backOffPolicy);// 设置重试策略,主要设置:重试异常类型、重试次数,默认3次Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();exceptionMap.put(RemoteAccessException.class, true);SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, exceptionMap);retryTemplate.setRetryPolicy(retryPolicy);// 执行Boolean execute = retryTemplate.execute(// 重试回调retryCallback -> {boolean result = RetryTask.task("retry1");log.info("调用的结果:{}", result);return result;},// 在所有尝试都用尽后进行有状态重试的回调recoveryCallback -> {log.info("已达到最大重试次数 或 或抛出了不重试的异常 后,进行一些操作");return false;});log.info("执行结果:{}", execute);return execute;}