ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring的Retry使用

2021-01-05 19:29:05  阅读:264  来源: 互联网

标签:Retry return String default Spring 重试 retry 使用 public


1、## 介绍
日常开发中经常需要调用第三方接口,有些接口需要在特定异常下进行重试,为了避免一直在调用接口,每次调用直接需要间隔一段时间,并且需要设置个上限,达到最大重试次数后抛出异常;对该异常进行一致性处理,按一致性补偿处理或者记录异常并推送提醒。
常用的做法是写个循环,不断调用接口,并设置睡眠时间;手动写重试方法需要考虑的异常问题较多,这里介绍个spring自带的retry,使用简单,即插即用。@Retryable也是通过AOP方式实现,因此重试的方法不能在同一类中调用。

2、## Retryable使用

在启动类中添加@EnableRetry注解

@EnableRetry
@ServletComponentScan
@SpringBootApplication
public class WebApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
    
    /**
     * 支持打成war包部署
     *
     * @date
     */
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }

}

业务service类中添加重试方法,通过@Retryable注解设置重试策略

int count = 0;
@Retryable(include = {RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))
    public void retryMethod() {
        System.out.println("执行重试count=" + count++ + " 执行时间" + LocalDateTime.now());
        /**
         * 调用第三方接口 异常
         */
        //抛出异常
        throw new RuntimeException();
    }

执行结果

执行重试count=0 执行时间2021-01-05T17:18:18.124
执行重试count=1 执行时间2021-01-05T17:18:20.124
执行重试count=2 执行时间2021-01-05T17:18:24.126

常用的参数

  1. value/include 处理的特定异常
  2. maxAttempts 最大重试次数,默认3次
  3. backoff 指定的重试策略,delay为第一次延迟时间(毫秒),multiplier为倍数

Retryable 注解中的各参数如下

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {

	/**
	 * Retry interceptor bean name to be applied for retryable method. Is mutually
	 * exclusive with other attributes.
	 * @return the retry interceptor bean name
	 */
	String interceptor() default "";

	/**
	 * Exception types that are retryable. Synonym for includes(). Defaults to empty (and
	 * if excludes is also empty all exceptions are retried).
	 * @return exception types to retry
	 */
	Class<? extends Throwable>[] value() default {};

	/**
	 * Exception types that are retryable. Defaults to empty (and if excludes is also
	 * empty all exceptions are retried).
	 * @return exception types to retry
	 */
	Class<? extends Throwable>[] include() default {};

	/**
	 * Exception types that are not retryable. Defaults to empty (and if includes is also
	 * empty all exceptions are retried).
	 * If includes is empty but excludes is not, all not excluded exceptions are retried
	 * @return exception types not to retry
	 */
	Class<? extends Throwable>[] exclude() default {};

	/**
	 * A unique label for statistics reporting. If not provided the caller may choose to
	 * ignore it, or provide a default.
	 *
	 * @return the label for the statistics
	 */
	String label() default "";

	/**
	 * Flag to say that the retry is stateful: i.e. exceptions are re-thrown, but the
	 * retry policy is applied with the same policy to subsequent invocations with the
	 * same arguments. If false then retryable exceptions are not re-thrown.
	 * @return true if retry is stateful, default false
	 */
	boolean stateful() default false;

	/**
	 * @return the maximum number of attempts (including the first failure), defaults to 3
	 */
	int maxAttempts() default 3;

	/**
	 * @return an expression evaluated to the maximum number of attempts (including the first failure), defaults to 3
	 * Overrides {@link #maxAttempts()}.
	 * @since 1.2
	 */
	String maxAttemptsExpression() default "";

	/**
	 * Specify the backoff properties for retrying this operation. The default is a
	 * simple {@link Backoff} specification with no properties - see it's documentation
	 * for defaults.
	 * @return a backoff specification
	 */
	Backoff backoff() default @Backoff();

	/**
	 * Specify an expression to be evaluated after the {@code SimpleRetryPolicy.canRetry()}
	 * returns true - can be used to conditionally suppress the retry. Only invoked after
	 * an exception is thrown. The root object for the evaluation is the last {@code Throwable}.
	 * Other beans in the context can be referenced.
	 * For example:
	 * <pre class=code>
	 *  {@code "message.contains('you can retry this')"}.
	 * </pre>
	 * and
	 * <pre class=code>
	 *  {@code "@someBean.shouldRetry(#root)"}.
	 * </pre>
	 * @return the expression.
	 * @since 1.2
	 */
	String exceptionExpression() default "";

	/**
	 * Bean names of retry listeners to use instead of default ones defined in Spring context
	 * @return retry listeners bean names
	 */
	String[] listeners() default {};

}

若要在达到最大次数后,处理特定异常,进行一致性任务处理,事务回滚或者推送提醒等,可通过@Recover处理,达到执行最大重试次数,会执行该方法。其中recover方法中的入参为重试中抛出的指定异常,且重试方法返回参数必须为void。

@Recover
    public void recover(RuntimeException e) {
        log.error("recover method", e);
        System.out.println("一致性处理补偿 : ");
    }

3、## 自定义策略
若需要控制第三方接口的超时时间,以及需要返回重试接口的错误异常信息,可以通过自定义策略模块,重写dowithRetry方法实现,自定义重试策略的超时时间。

public void retryPolicy() {
        RetryTemplate template = new RetryTemplate();

        TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
        policy.setTimeout(6000L);

        template.setRetryPolicy(policy);

        String result = template.execute(new RetryCallback<String, RuntimeException>() {
            @Override
            public String doWithRetry(RetryContext context) {
                // Do stuff that might fail, e.g. webservice operation
                return "";
            }

        });
    }

其中doWithRetry方法的返回参数可按需要返回所要的类型,TimeoutRetryPolicy为超时的策略继承了RetryPolicy接口。

4、## 总结
spring自带的重试机制,使用方便,简单,可指定重试异常和重试间隔时间等;并且提供自定义重试模板方法,自定义重试策略,可对接口调用超时异常进行处理重试。spring自带的重试方法在spring家族使用广泛,spring batch和spring单例等方法中都有使用。

标签:Retry,return,String,default,Spring,重试,retry,使用,public
来源: https://blog.csdn.net/daiming573/article/details/112250182

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有