分享免费的编程资源和教程

网站首页 > 技术教程 正文

Spring Boot-整合Retry框架重试机制-Retryable注解实现重试(一)

goqiw 2024-09-25 20:13:13 技术教程 39 ℃ 0 评论

今日分享

每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您。

架构开源地址:https://gitee.com/msxy

Retry业务场景介绍

项目中为了保证处理更健壮,容错性更高,更不容易失败,使用自动重试的失败的操作,可提高后续操作的可用性,保证容错性。Spring实提供了自动重试机制,功能简单实用。当错误引起失败是暂时性的情况下,非常适用。比如操作中暂时的网络故障,或者数据库操作由暂时锁引起的异常等。

在微服务中通常都提供了重试与超时配置,比如SpringCloud的Feign组件。在SpringBoot的单应用项目中,我们则可以使用Spring提供的Spring Retry实现自动重试功能。

Retry框架介绍

Retry重试框架,支持AOP切入的方式使用,支持注解;重试次数、重试延迟、重试触发条件、重试的回调方法等功能来实现重试机制。

项目中我们可以通过两种不同的方式使用Spring Retry重试功能,一种是@Retryable注解的方式,另一种是RetryTemplate方式。

springboot整合Retry实现Retryable注解重试

pom文件加入依赖

<dependency>
  <groupId>org.springframework.retry</groupId>
  <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
</dependency>

容器启动类上添加注解@EnableRetry

也可以在任一的@Configuration配置类上添加@EnableRetry注解开启Spring Retry的重试功能。

@EnableRetry
@SpringBootApplication
@MapperScan("com.qingfeng.*.mapper")
@EnableMyRedis
@EnableMyProtect
@ServletComponentScan
//@ServletComponentScan("com.qingfeng.framework.servlet")
public class QingfengApplication {
    
    @Value("${spring.application.name}")
    private  String application;
    
    public static void main(String[] args) {
        SpringApplication.run(QingfengApplication.class, args);
    }
    
    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer() {
        return (registry) -> registry.config().commonTags("application", application);
    }
}

创建测试Service

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TTestServiceImpl implements ITestService {


    private final static int TOTAL_NUM = 100000;

    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 5000L, multiplier = 2))
    public int getRetryNum(int num) throws Exception {
        System.out.println("getRemainingAmount======" + DateTimeUtil.getDateTimeStr());
        if (num <= 0) {
            throw new Exception("数量不对");
        }
        System.out.println("getRemainingAmount======执行结束");
        return TOTAL_NUM - num;
    }

    @Recover
    public int recover(Exception e) {
        // 回调方法,业务逻辑处理
        return -1;
    }

}

@Retryable:标记当前方法使用重试机制

value:触发重试机制的条件,当遇到Exception时,会重试

maxAttempts :设置最大重试次数,默认为3次

delay:重试延迟时间,单位毫秒,即距离上一次重试方法的间隔

multiplier:delay重试延迟时间的间隔倍数,即第一次为5秒,第二次为5乘以2为10秒,依此类推

创建测试Controller

    @GetMapping("/retryTest")
    public String retryTest(@RequestParam int num) throws Exception {
        int retrynum = testService.getRetryNum(num);
        log.info("剩余数量===" + retrynum);
        return "success";
    }

运行测试

在浏览器中输入:http://localhost:8090/common/test/retryTest?num=0

可以看到,第一次用时5S,第二次用时10S,第三次用时15S;

最后会抛出异常,可以在上层代码进行try-catch处理相关业务逻辑;

也可以写回调方法处理,在TestServiceImpl类中添加如下代码,@Recover:当重试方法发生异常时,会执行该回调方法

    @Recover
    public int recover(Exception e) {
        // 回调方法,业务逻辑处理
        return -1;
    }

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表