SpringBoot中使用spring-retry解决重试

使用场景

在日常开发过程中,难免会与第三方接口发生交互,例如:短信发送、远程服务调用、争抢锁等场景,当正常调用发生异常时,例如:网络抖动,这些间歇性的异常在一段时候之后会自行恢复,程序为了更加健壮并且更不容易出现故障,需要重新触发业务操作,以防止间歇性的异常对程序照成的影响。

如何使用

1、 引入spring-retry
这里我们还引入了 aop 的依赖,因为 spring-retry 的原理就是基于 aop 来实现的

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、开启spring-retry
在启动类增加注解@EnableRetry

@SpringBootApplication
@EnableRetry
public class MyApplication {

    public static void main(String[] args) {
        // 启动spring-boot-plus
        ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);
        // 打印项目信息
        PrintApplicationInfo.print(context);
    }

}

3、在方法上添加@Retryable


    @Retryable( value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 2))
    public String testRetry() {
        return "执行成功";
    }

@Retryable 注解

  • value,可重试的异常类型。含义同include。默认为空(如果excludes也为空,则重试所有异常)

  • include:可重试的异常类型。默认为空(如果excludes也为空,则重试所有异常)

  • exclude:无需重试的异常类型。默认为空(如果includes也为空,则重试所有异常)

  • maxAttempts:最大重试次数(包括第一次失败),默认为3次

  • backoff:重试等待策略,下面会在@Backoff中介绍

  • recover:表示重试次数到达最大重试次数后的回调方法

    @Backoff 注解

  • delay,重试之间的等待时间(以毫秒为单位)

  • maxDelay,重试之间的最大等待时间(以毫秒为单位)

  • multiplier,指定延迟的倍数

  • delayExpression,重试之间的等待时间表达式

  • maxDelayExpression,重试之间的最大等待时间表达式

  • multiplierExpression,指定延迟的倍数表达式

  • random,随机指定延迟时间

4、重试耗尽后回调
当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,重试耗尽实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。

@Recover
    public String recoverTest(RuntimeException e) {
        return "回调方法-" + e.getMessage();
    }
  • 方法的返回值必须与 @Retryable 方法一致
  • 方法的第一个参数,必须是 Throwable 类型的,建议是与 @Retryable 配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover 方法中有的)
  • 该回调方法与重试方法写在同一个实现类里面
  • 若同一个实现类中有多个回调方法,我们需要使用 recover 属性指定回调的方法名,如下面代码,指定回调的方法名是recoverTest1
@Retryable(recover = "recoverTest1", value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 2))
    public String testRetry() {
        return "执行成功";
    }

    @Recover
    public String recoverTest(RuntimeException e) {
        return "回调方法-" + e.getMessage();
    }

    @Recover
    public String recoverTest1(RuntimeException e) {
        return "回调方法-" + e.getMessage();
    }

注意事项

  • 由于是基于 AOP 实现,所以不支持类里自调用方法
  • 如果重试失败需要给 @Recover 注解的方法做后续处理,那这个重试的方法不能有返回值,只能是 void
  • 方法内不能使用 try catch,只能往外抛异常
  • @Recover 注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是 @Retryable 抛出的异常,否则无法识别,可以在该方法中进行日志处理。

demo

1、controller

@Slf4j
@RestController
@RequestMapping("/partyManageInfo")
public class ManageInfoController extends BaseController {
	private final ManageInfoServiceImpl manageInfoServiceImpl;


    public ManageInfoController(ManageInfoServiceImpl manageInfoServiceImpl) {
        this.manageInfoServiceImpl = manageInfoServiceImpl;
    }
    /**
     * 修改党委管理干部信息
     */
    @PostMapping("/test")
    @ApiOperation(value = "测试重试", notes = "测试重试")
    public ApiResult<Boolean> testRetry() {
        manageInfoServiceImpl.testRetry();
        return ApiResult.ok();
    }
}

3、service

@Slf4j
@Service
public class ManageInfoServiceImpl{
	int a = 0;

    @Retryable( value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 2))
    public String testRetry() {
        a++;
        System.out.println(a + " - 调用时间是" + LocalTime.now());
        if (a < 10) {
            throw new RuntimeException("未满足条件");
        }
        return "执行成功";
    }

    @Recover
    public String recoverTest(RuntimeException e) {
        System.out.println("回调方法调用时间是-"+ LocalTime.now()+",异常信息-" + e.getMessage());
        return "回调方法-" + e.getMessage();
    }
}

3、调接口测试结果
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果在右键菜单没有找到"Git Bash"选项,可能是因为没有正确添加该选项到注册表。您可以按照以下步骤尝试添加Git Bash到右键菜单: 1. 打开注册表编辑器,可以在开始菜单搜索"regedit"来找到并打开它。 2. 导航到HKEY_CLASSES_ROOT\Directory\Background\shell键。 3. 在shell键下,如果没有"Git Bash Here"项,则右键点击shell键,选择"新建",然后命名为"Git Bash Here"。 4. 在"Git Bash Here"项下,右键点击,选择"新建",然后命名为"command"。 5. 在"command"项,双击"(默认)"值,并将其更改为"安装根目录\Git\bin\bash.exe" "--cd=%V"。 6. 关闭注册表编辑器。 现在,您应该能够在文件夹的背景上右键点击,看到"Git Bash Here"选项了。请确保替换步骤5的"安装根目录"为您实际的Git安装路径。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [GitBash和GitGui右键失效解决方法](https://download.csdn.net/download/yjs010101010/10146212)[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_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Git右键没有Git Bash Here的解决办法](https://blog.csdn.net/qq_27951873/article/details/123525101)[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_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值