指数退避算法& spring retry

指数退避算法

本节转载自: https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=zh-cn

指数退避算法是适用于网络应用的标准错误处理策略,使用这种策略时,客户端会定期重试失败的请求,并不断增加各次请求之间的延迟时间。

示例算法

指数退避算法以指数方式重试请求(不断增加各次重试之间的等待时间,直到达到最大退避时间)。示例如下:

  1. 客户端发出请求。
  2. 如果请求失败,请等待 1 + random_number_milliseconds 秒后再重试请求。
  3. 如果请求失败,请等待 2 + random_number_milliseconds 秒后再重试请求。
  4. 如果请求失败,请等待 4 + random_number_milliseconds 秒后再重试请求。
  5. 依此类推,等待时间上限为 maximum_backoff

等待时间达到上限后,您可以继续等待并重试,直到达到重试次数上限(但接下来的重试操作不会增加各次重试之间的等待时间)。

其中:

  • 等待时间为 min(((2^n)+random_number_milliseconds), maximum_backoff),其中,n 会在每次迭代(请求)后增加 1。
  • random_number_milliseconds 是小于或等于 1000 的毫秒数(随机值)。这有助于避免出现以下情况:许多客户端在某些情况下全部同步进行处理并同时执行重试操作,导致同步发送每一波请求。每次重试请求后,系统都应重新计算 random_number_milliseconds 值。
  • maximum_backoff 通常为 32 或 64 秒。哪个值更为适当,这取决于用例。
  • 达到 maximum_backoff 时间后,您可以继续重试。 此后执行的重试不需要继续增加退避时间。
    • 例如,如果客户端使用的 maximum_backoff 时间为 64 秒,则在达到此值后,客户端可以每 64 秒重试一次。在某个时刻,应阻止客户端无限重试。


Spring 退避算法

@Retryable

引用:https://www.baeldung.com/spring-retry

maven依赖

   <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
            <version>1.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>

java code

@Service
public class OrderService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

	    private AtomicInteger loop = new AtomicInteger(1);
    private Instant instantBefore;
    @Retryable(
            value = RuntimeException.class , //抛出该异常时,进行重试
            maxAttempts=12,  // 最大重试次数,超过直接抛出异常
            backoff =
            @Backoff(
                    delay=500, //初始delay时间
                    multiplier = 2, // 设置为2时,可以理解为
                    maxDelay=10000, // min(delay * multiplier^(attempt - 1), maxDelay)
                    random =  false //是否使用随机数
            )
    )
    public void readOrder(String orderId){
        Instant now = Instant.now();
        long  gap =  instantBefore == null ? 0 : Duration.between(instantBefore, now).toMillis();
        logger.info("{} --- time-gap :{}",loop.getAndIncrement(),gap);
        instantBefore = now;

        if( 1 < 2) throw new RuntimeException(); // 抛出异常,进行重试
    }
}

上述算法可以描述为: min(delay * multiplier^(attempt - 1), maxDelay),

multiplier=2 && random=true,可以近似理解为指数退避算法

执行结果

在这里插入图片描述

RetryTemplate


    public void readOrder(String orderId){
        int retryCount = 3;
        RetryTemplate retryTemplate = RetryTemplate.builder()
                .maxAttempts(retryCount)
            //    .uniformRandomBackoff(10000, 15000)
                .exponentialBackoff(500,2, 10000)
                .retryOn(RetryException.class) //抛出该异常时,进行重试
                .build();


        retryTemplate.execute(context -> {
            System.out.println("xx");
            return null;
        });
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Retry是一个基于AOP实现的重试机制,用于处理应用程序中可能发生的失败情况,比如调用第三方接口失败等。通过延时重试、间隔递增重试等方式,Spring Retry可以帮助我们实现自动重试的功能。 要使用Spring Retry,需要在项目的依赖中引入spring-retry库。可以在项目的Maven或Gradle配置文件中添加相应的依赖项。例如,在Maven中添加以下依赖项: ```xml <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.2.4.RELEASE</version> </dependency> ``` 使用Spring Retry时,可以在需要重试的方法上使用`@Retryable`注解。同时,在配置类上添加`@EnableRetry`注解来启用声明式重试功能。例如: ```java @EnableRetry @Configuration public class RetryConfiguration { @Bean public HelloService helloService() { return new HelloService(); } } ``` 通过以上配置,我们可以在`HelloService`中的方法上使用`@Retryable`注解来实现自动重试的功能。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringRetryspring的重试机制)——只需一个注解](https://blog.csdn.net/qq_48607414/article/details/128042278)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Spring(34)——Spring Retry介绍](https://blog.csdn.net/elim168/article/details/90320848)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值