Spring优雅重试@EnableRetry

  1. 如果不用spring的写法

// 简单递归+次数限制+线程睡眠

package com.example.springexample.springretry;

/**
 * @desc: RetryDemo
 * @author: pmdream
 * @date: 2023/3/15 1:51 AM
 */
public class RetryDemo {

    public static void retry(int i) {
        if (i <= 3) {
            i++;
            try {
                if (method()) {
                    System.out.println("成功");
                } else {
                    Thread.sleep(1000);
                    System.out.println("重试:" + i + "次");
                    retry(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static boolean method() {
        System.out.println("do some thing");
        return false;
    }

    public static void main(String[] args) {
        retry(0);
    }
}

结果:

do some thing
重试:1次
do some thing
重试:2次
do some thing
重试:3次
do some thing
重试:4次
  1. 使用spring的优雅写法

引入 maven 依赖:

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

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
如果不增加切面maven依赖,会报错:
Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut

启动类需要加入:

@EnableRetry

package com.example.springexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

@SpringBootApplication
@EnableRetry
public class SpringExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringExampleApplication.class, args);
    }

}

测试方法:

package com.example.springexample.springretry;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringRetryServiceImplTest {

    @Autowired
    ISpringRetryService springRetryService;

    @Test
    public void method() {
        springRetryService.method();
    }
}
package com.example.springexample.springretry;

/**
 * @desc: ISpringRetryService
 * @author: pmdream
 * @date: 2023/3/15 1:29 AM
 */
public interface ISpringRetryService {
    void method();
}
package com.example.springexample.springretry;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

/**
 * @desc: SpringRetryServiceImpl
 * @author: pmdream
 * @date: 2023/3/15 1:27 AM
 */
@Service
public class SpringRetryServiceImpl implements ISpringRetryService {

    @Retryable(value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 5000L))
    @Override
    public void method() {
        System.out.println(System.currentTimeMillis() + "method exec");
        doSomeThing();
    }

    private void doSomeThing() {
        // do some thing
        throw new RuntimeException("throw exception");
    }
}

测试结果:

可以看到,时间是5000毫秒一次

1678815994214method exec
1678815999218method exec
1678816004221method exec
1678816009223method exec

@Retryable注解中的参数说明:

maxAttempts :最大重试次数,默认为3,如果要设置的重试次数为3,可以不写;
value:抛出指定异常才会重试
include:和value一样,默认为空,当exclude也为空时,默认所有异常
exclude:指定不处理的异常
backoff:重试等待策略,默认使用@Backoff的value默认为1000L

@Backoff注解中的参数说明:

delay:每次重试延迟毫秒数,默认为0L
value:delay的别名,默认为1000L,当delay>0时,value将会被忽略
maxDelay:最大延迟毫秒数,默认为0L,
multiplier:(指定延迟倍数)默认为0;大于0时生效;如果delay等于2,multiplier等于2,则第一次重试为2秒,第二次为4秒,第三次为8秒…
random:随机值加权,默认为false;当multiplier>0时,上次延迟毫秒 < 延迟时间 < 最大延迟 * multiplier
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值