• springretry使用


    Spring Retry提供了自动重新调用失败的操作的功能。这在错误可能是暂时性的(例如瞬时网络故障)的情况下很有用。Spring Retry提供对流程和基于策略的行为的声明式控制,易于扩展和自定义。接下来,本文将带大家了解 Spring Retry 的使用方法和部分源码解析

    引入spring-retry 相关包

    使用spring-retry ,我们只需引入spring-retry 和 aop 的包即可,以 maven 为例:

    org.springframework.retry spring-retry org.springframework spring-aspects 使用 spring-retry

    @EnableRetry

    首先我们需要使用@EnableRetry 注解启用Retry,注册 Retryable 的切点和拦截方法

    @Retryable

    在我们想要重试的方法上增加@Retryable 注解

    @Retryable 参数

    interceptor

    自定义重试拦截器bean名称,用于可重试方法。与其他属性互斥。

    //新增自定义拦截器
    @Component
    public class RetryTestInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
    //实现具体的拦截策略
    System.out.println("retry test interceptor");
    return invocation.proceed();
    }
    }
    //参数为自定义拦截器的 bean 名称
    @Retryable(interceptor = "retryTestInterceptor")
    value

    include

    value 与 include 含义相同,表示可重试的异常类型。默认为空,如果同时exclude 也为空则会重试所有异常。但在使用时需要注意

    @Retryable(value = {RuntimeException.class})
    exclude

    不可重试的异常类型。默认为空(如果include也为为空,将重试所有异常)。如果include为空但exclude 不为空,则重试非 exclude 中的异常

    @Retryable(exclude = {RuntimeException.class})
    label

    统计报告的唯一标签。如果未提供,则调用者可以选择忽略它或提供默认值。

    stateful

    标记为表示重试是有状态的,默认为 false,在 interceptor 参数中有提到,参数不同使用的拦截器不同,后面我们会讲到不同拦截的作用

    maxAttempts

    最大重试次数,默认是 3

    maxAttemptsExpression

    最大尝试次数的表达式,表达式一旦设置了值,则会覆盖 maxAttempts 的值

    //执行 testBean 的 attempts() 方法,获取重试次数
    @Retryable(maxAttemptsExpression = "#{@testBean.attempts()}")
    backoff

    用于重试退避策略,比如每隔2s 重试一次,每次重试间隔时间等等,详见@Backoff注解

    //第一次延迟 1s 重试,第二次延迟 2s,第三次延迟 4s,...
    @Retryable(backoff = @Backoff(delay = 1000L, multiplier = 2))
    exceptionExpression

    异常处理表达式,ExpressionRetryPolicy中使用,执行完父类的 canRetry 之后,需要校验 exceptionExpression 的值,为 true 则可以重试

    //执行 testBean 的 shouldRetry() 方法,如果为 true,则允许重试
    @Retryable(exceptionExpression = "#{@testBean.shouldRetry()}")
    listeners

    重试监听器的 bean 名称。

    重试策略

    Spring Retry 提供了多种重试策略,比如

    SimpleRetryPolicy

    	默认重试策略,简单的重试策略,它对一组命名的异常*(和子类)重试固定次数。尝试次数包括初始尝试
    

    AlwaysRetryPolicy

    	始终允许重试策略,
    

    MaxAttemptsRetryPolicy

    	简单重试策略,仅通过重试次数判断是否能够重试。不建议直接使用它。
    

    TimeoutRetryPolicy

    	超时重试策略,仅在尚未超时的情况下允许重试。
    

    NeverRetryPolicy

    	允许第一次尝试,但不允许重试。
    

    还有很多重试策略就不一一介绍了,大家可以自行了解,当然我们也可以通过实现 RetryPolicy 自定义重试策略。

    退避策略

    退避策略就是我们上面提到的 @Backoff 注解实现的功能,那么我们首先看一下@Backoff 的参数

    @Backoff 参数

    value

    	默认为 1000, 与 delay 作用相同,表示延迟的毫秒数。当 delay 非 0 时,此参数忽略。
    

    delay

    	默认为 0。在指数情况下用作初始值,在统一情况下用作*的最小值。当此元素的值为0时,将采用元素value的值,否则将采用此元素的值,并且将忽略value。
    

    maxDelay

    	默认为 0。重试之间的最大等待时间(以毫秒为单位)。如果小于delay,那么将应用默认值为30000L
    

    multipler

    	默认为 0。如果为正,则用作乘法器以生成下一个退避延迟。返回一个乘法器,用于计算下一个退避延迟
    

    delayExpression

    	评估标准退避期的表达式。在指数情况下用作初始值*,在均匀情况下用作最小值。覆盖 delay。
    

    maxDelayExpression

    	该表达式计算重试之间的最大等待时间(以毫秒为单位)。 如果小于 delay,那么将应用30000L 为默认值。覆盖 maxDelay。
    

    multiplierExpression

    	评估为用作乘数的值,以生成退避的下一个延迟。覆盖multiplier。 返回一个乘数表达式,用于计算下一个退避延迟
    

    random

    	默认为 false,在指数情况下 multiplier> 0 将此值设置为 true 可以使后退延迟随机化,从而使最大延迟乘以前一延迟,并且两个值之间的分布是均匀的。
    

    @Backoff 的参数会影响我们使用哪种退避策略

    FixedBackOffPolicy

    	默认退避策略,每 1 秒重试 1 次
    

    ExponentialBackOffPolicy

    	指数退避策略,当设置 multiplier 时使用,每次重试时间间隔为 当前延迟时间 * multiplier。
    

    ExponentialRandomBackOffPolicy

    	指数随机退避策略。在指数退避策略的基础上增加了随机性。具体策略查看 getSleepAndIncrement() 方法
    

    UniformRandomBackOffPolicy

    	均匀随机策略,设置 maxDely 但没有设置 multiplier 时使用,重试间隔会在 maxDelay 和 delay 间随机
    

    同样的,我们可以通过实现 BackOffPolicy 来实现自定义的退避策略

    @Recover

    作为恢复处理程序的方法调用的注释。重试方法最终会调用标注了@Recover 的方法

    合适的恢复*处理程序具有 Throwable 类型作为第一个参数,并且具有与要从其中进行恢复的 @Retryable 方法相同类型的返回值。 Throwable 第一个参数是可选的(但是,如果没有其他参数匹配,则不带该参数的方法将被调用)。从失败方法的参数列表中依次填充后续参数。

    具体使用

    主启动类增加@EnableRetry重试注解

    @EnableRetry
    @SpringBootApplication
    public class ScrapyApplication {
    public static void main(String[] args) {
    SpringApplication.run(ScrapyApplication.class, args);
    }
    }
    在需要重试的方法上增加@Retryable注解

    @Slf4j
    @Component
    public class RetryService {
    @Retryable(value = Exception.class, maxAttempts = 3, listeners = {"myRetryListener"})
    public void test(Integer id) {
    try {
    int num = RandomUtil.randomInt(0, 1);
    int i = id / num;
    log.info("正常运行了");
    } catch (Exception e) {
    log.error("程序报错了:{}", e.getMessage());
    throw new RuntimeException(e.getMessage());
    }
    }

    @Recover
    public void testRecover() {
    log.error("~仍然报错,停止重试~");
    }

    }
    listener

    @Slf4j
    @Component
    public class MyRetryListener extends RetryListenerSupport {
    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
    log.info("监听到重试过程关闭了");
    log.info("=");
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
    log.info("监听到重试过程错误了");
    }

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
    log.info("
    =");
    log.info("监听到重试过程开启了");
    return true;
    }

    }
    站在巨人肩膀上摘苹果

    https://blog.csdn.net/a742172349/article/details/106199939

    https://blog.csdn.net/weixin_41307800/article/details/124604598

  • 相关阅读:
    FAST特征点检测算法
    ORB算法介绍(转)
    centos 安装MATLAB :设置回环设备失败: 没有那个文件或目录
    特征检测和特征匹配方法
    摄像机标定-- 张正友标定推导详解
    sublime text plugins
    使用Sublime Text搭建python调试环境[转]
    python OS 模块
    python 守护进程,监控进程
    python 带正则的search 模块
  • 原文地址:https://www.cnblogs.com/eternityz/p/16280001.html
Copyright © 2020-2023  润新知