Spring Boot集成 Spring Retry 实现容错重试机制并附源码

Spring Boot集成 Spring Retry 实现容错重试机制并附源码

码农世界 2024-06-15 后端 88 次浏览 0个评论

Spring Boot集成 Spring Retry 实现容错重试机制并附源码

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志

🎐 个人CSND主页——Micro麦可乐的博客

🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战

🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战

🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解

💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程

🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整

如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

Spring Boot集成 Spring Retry 实现容错重试机制

  • 1、前言
  • 2、什么是 Spring Retry?
  • 3、开始简单集成
  • 4、Spring Retry的高级配置
    • ❶ 自定义重试策略
      • canRetry方法的介绍
      • open方法的介绍
      • close方法的介绍
      • registerThrowable方法的介绍
      • ❷ 使用 RetryTemplate
      • 5、代码汇总
      • 6、总结

        1、前言

        本文对应源码下载地址: https://download.csdn.net/download/lhmyy521125/89430153 无需积分

        在日常开发过程中,我们经常会与第三方接口进行交互,例如:短信发送、远程服务调用、争抢锁等场景,当正常调用发生异常时,例如:网络延迟、服务宕机或临时故障等问题,会导致本次请求交互失败,而借助 Spring Retry 能够帮助我们在方法调用失败时自动重试,从而提高系统的稳定性和健壮性。

        本文跟着博主由浅入深一起来学习 Spring Retry!

        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

        2、什么是 Spring Retry?

        Spring Retry 是一个用于简化 Java 方法重试逻辑的库,它能够在方法调用失败时自动重试,并提供了丰富的配置选项,支持重试次数、重试间隔时间、异常类型等配置。通过使用 Spring Retry,可以方便地在 Spring Boot 应用中实现容错和重试机制。

        Spring Retry 的特性

        • 自动重试:当方法调用失败时,根据配置的重试策略自动重试
        • 支持多种异常类型:可以配置在遇到特定异常时重试,如 IOException、SQLException 等
        • 重试间隔控制:支持配置重试间隔时间,可以设置固定间隔或指数增长间隔
        • 自定义重试策略:提供了灵活的重试策略接口,可以实现自定义的重试逻辑

        3、开始简单集成

        构建你的 Spring Boot 项目,在pom.xml中引入依赖

        
            org.springframework.retry
            spring-retry
        
        
            org.springframework.boot
            spring-boot-starter-aop
        
        

        配置 Spring Retry 可以通过注解或配置文件进行配置。下面展示如何使用注解方式配置

        使用@EnableRetry注解开启

        在主类 或对应配置类上加@EnableRetry注解,表示启用重试机制

        @SpringBootApplication
        @EnableRetry
        public class Application {
            public static void main(String[] args) {
                SpringApplication.run(Application.class, args);
            }
        }
        

        使用 @Retryable 注解

        @Retryable 注解是 Spring Retry 的核心注解,用于标记需要重试的方法。示例代码如下:

        import org.springframework.retry.annotation.Backoff;
        import org.springframework.retry.annotation.Retryable;
        import org.springframework.stereotype.Service;
        @Service
        public class RetryService {
        	//初始化重试次数
            private int attempt = 0;
            @Retryable(value = {RuntimeException.class}, maxAttempts = 5, backoff = @Backoff(delay = 2000))
            public String retryMethod() {
                attempt++;
                System.out.println("重试次数Attempt: " + attempt);
                if (attempt < 3) {
                    throw new RuntimeException("出现故障, 重试中...");
                }
                return "Success!";
            }
        }
        

        配置参数说明

        value 指定了需要重试的异常类型,这里是 RuntimeException

        maxAttempts 设置了最大重试次数,这里是 5 次

        backoff 设置了重试间隔,使用 @Backoff 注解指定延迟时间,单位是毫秒,这里是 2000 毫秒(2秒)

        创建一个controller,用于调用重试方法,并测试重试逻辑:

        import com.example.demo.service.RetryService;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RestController;
        @RestController
        public class RetryController {
            @Autowired
            private RetryService retryService;
            @GetMapping("/retry")
            public String retry() {
                try {
                    return retryService.retryMethod();
                } catch (Exception e) {
                    return "重试失败: " + e.getMessage();
                }
            }
        }
        

        接口请求测试

        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

        观察控制台

        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

        测试你会发现接口请求过程中,控制台一直输出了三次重试次数后成功返回,你以为Spring Retry 就这么点东西?我们继续往下看

        4、Spring Retry的高级配置

        ❶ 自定义重试策略

        在某些情况下,默认的重试策略可能无法满足需求,这时可以通过实现 RetryPolicy 接口来自定义重试策略,控制重试的逻辑和条件

        import org.springframework.retry.RetryContext;
        import org.springframework.retry.RetryPolicy;
        public class CustomRetryPolicy implements RetryPolicy {
        	
            private static final int MAX_RETRIES = 3;
            @Override
            public boolean canRetry(RetryContext context) {
                // 检查重试次数
                int retryCount = context.getRetryCount();
                if (retryCount >= MAX_RETRIES) {
                    return false; // 如果重试次数达到最大值,不再重试
                }
                // 检查异常类型
                Throwable lastException = context.getLastThrowable();
                if (lastException instanceof MyCustomException) {
                    // 如果是我们关心的特定异常类型,允许重试
                    return true;
                }
                // 其他情况下不允许重试
                return false;
            }
            //MyCustomException 是你定义的异常类型
            public class MyCustomException extends Exception { /* ... */ }
        	
        	//在重试操作开始时创建新的上下文对象,用于存储重试信息
        	@Override
            public RetryContext open(RetryContext retryContext) {
                return null;
            }
        	//在重试操作结束时执行清理或记录操作
            @Override
            public void close(RetryContext retryContext) {
            }
        	//在重试过程中遇到异常时记录异常信息
            @Override
            public void registerThrowable(RetryContext retryContext, Throwable throwable) {
            }
        }
        

        canRetry方法的介绍

        boolean canRetry(RetryContext context);
        

        canRetry 方法是重试策略的核心逻辑,通过检查当前的重试上下文信息,决定是否可以继续进行重试。通常会根据重试次数、异常类型等条件来判断是否继续重试

        作用:判断是否应该继续进行重试操作

        参数:RetryContext context,表示当前的重试上下文,包含了重试次数、上次异常等信息

        返回值:boolean,返回 true 表示可以继续重试,返回 false 表示停止重试

        open方法的介绍

        RetryContext open(RetryContext parent);
        

        在重试操作开始时,Spring Retry 会调用 open 方法创建一个新的 RetryContext,这个上下文对象会在整个重试过程中传递,用于存储重试相关的信息

        作用:创建并返回一个新的 RetryContext 对象,表示一次新的重试操作的上下文信息

        参数:RetryContext parent,表示父级上下文,如果没有父级上下文则为 null

        返回值:RetryContext,表示新的重试上下文

        close方法的介绍

        当重试操作完成后,无论是否成功,Spring Retry 都会调用 close 方法,可以在这个方法中执行一些清理操作或记录日志

        void close(RetryContext context);
        

        作用:在重试操作完成时(无论成功或失败)调用,用于清理或记录重试操作的结束

        参数:RetryContext context,表示当前的重试上下文

        registerThrowable方法的介绍

        void registerThrowable(RetryContext context, Throwable throwable);
        

        在重试过程中,如果遇到异常,Spring Retry 会调用 registerThrowable 方法,将异常信息记录到 RetryContext 中。这个信息可以在后续的重试操作中使用

        作用:在重试过程中遇到异常时调用,用于记录当前的异常信息

        参数:RetryContext context,表示当前的重试上下文

        参数:Throwable throwable,表示当前遇到的异常

        在Spring配置中使用自定义 RetryPolicy ,同时也可以配置定制 RetryTemplate

        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.retry.backoff.FixedBackOffPolicy;
        import org.springframework.retry.support.RetryTemplate;
        @Configuration
        public class RetryConfig {
            @Bean
            public RetryTemplate retryTemplate() {
                RetryTemplate retryTemplate = new RetryTemplate();
                // 设置自定义的RetryPolicy
                CustomRetryPolicy retryPolicy = new CustomRetryPolicy(5);
                // 还可以设置其他的策略,如BackoffPolicy等  
                FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
                backOffPolicy.setBackOffPeriod(2000);
                retryTemplate.setRetryPolicy(retryPolicy);
                retryTemplate.setBackOffPolicy(backOffPolicy);
                return retryTemplate;
            }
        }
        

        ❷ 使用 RetryTemplate

        RetryTemplate 是 Spring Retry 提供的一个模板类,允许我们更细粒度地控制重试逻辑。下面是使用 RetryTemplate 的例子

        import org.springframework.retry.support.RetryTemplate;
        import org.springframework.stereotype.Service;
        @Service
        public class TemplateRetryService {
            private final RetryTemplate retryTemplate;
            public TemplateRetryService(RetryTemplate retryTemplate) {
                this.retryTemplate = retryTemplate;
            }
            public String executeWithRetry() {
                return retryTemplate.execute(context -> {
                    System.out.println("TemplateRetryService执行重试..");
                    if (Math.random() < 0.7) {
                        throw new RuntimeException("重试失败");
                    }
                    return "Success!";
                });
            }
        }
        

        5、代码汇总

        Spring Retry 也是可以与 Spring AOP 配合使用,通过切面拦截方法调用,实现全局的重试逻辑,只需要创建一个切面即可

        import org.aspectj.lang.annotation.Aspect;
        import org.aspectj.lang.annotation.Before;
        import org.springframework.retry.annotation.Retryable;
        import org.springframework.stereotype.Component;
        @Aspect
        @Component
        public class RetryAspect {
            @Before("@annotation(org.springframework.retry.annotation.Retryable)")
            public void beforeRetry() {
                System.out.println("执行重试前...");
                //比如记录请求发起的时间等
            }
        }
        

        讲解了这么多,我们还是把代码汇总一下,进行一次演示,编写一个Controller用来测试两个重试服务

        @RestController
        @RequestMapping("/api")
        public class RetryController {
            @Autowired
            private RetryService retryService;
            @Autowired
            private TemplateRetryService templateRetryService;
            @GetMapping("/retry")
            public String retry() {
                try {
                    return retryService.retryMethod();
                } catch (Exception e) {
                    return "重试失败: " + e.getMessage();
                }
            }
            @GetMapping("/template-retry")
            public String templateRetry() {
                return templateRetryService.executeWithRetry();
            }
        }
        

        最终代码结构如下:(目的只是为了演示忽略都在一个包中)

        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

        再次运行测试,分别测试 /api/retry 接口以及模板重试服务的接口 /api/template-retry,结果如下:

        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

        OK,至此 Spring Retry 的介绍以及使用已经讲完了,小伙伴们可以根据代码片段自行定制自己的重试策略

        6、总结

        Spring Retry 是一个强大的工具,能够帮助我们在系统出现临时故障时自动重试,提高系统的稳定性和健壮性。在实际开发中,根据具体的业务需求和系统情况,合理配置和使用 Spring Retry,可以显著提升系统的可靠性。

        本文的代码主要是演示使用,小伙伴们可以根据自己业务需求进行修改升级。如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论


        Spring Boot集成 Spring Retry 实现容错重试机制并附源码

转载请注明来自码农世界,本文标题:《Spring Boot集成 Spring Retry 实现容错重试机制并附源码》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,88人围观)参与讨论

还没有评论,来说两句吧...

Top