• 基于springboot整合spring-retry


    1、背景

    本系统调用外围系统接口(http+json),但是发现有时外围系统服务不太稳定,有时候会出现返回一串xml或者gateway bad的信息,导致调用失败,基于这一原因,采用基于springboot,整合spring-retry的重试机制到系统工程中,demo已经放到github上。

    2、解决方案

    简要说明:demo工程基于springboot,为了方便验证,采用swagger进行测试验证。

    2.1 pom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.0</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.laowang</groupId>
        <artifactId>springretry</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springretry</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--retry-->
            <dependency>
                <groupId>org.springframework.retry</groupId>
                <artifactId>spring-retry</artifactId>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
            </dependency>
            <!--swagger-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.7.0</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.7.0</version>
            </dependency>
    
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    重点说明:aop的gav必须有,否则会跑不起来。

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

    2.2 applicat启动类

    package com.laowang.springretry;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.retry.annotation.EnableRetry;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    @EnableRetry
    @EnableSwagger2
    @SpringBootApplication
    public class SpringretryApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringretryApplication.class, args);
        }
    }
    

    说明:两个标签而已

    @EnableRetry
    @EnableSwagger2
    

    2.3 controller类

    /**
     * @description: TODO
     * @author Administrator
     * @date 2021/6/2 14:55
     * @version 1.0
     */
    package com.laowang.springretry.controller;
    import com.laowang.springretry.service.RetryService;
    import io.swagger.annotations.Api;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @Api("重试测试类")
    @RestController
    public class RetryController {
        @Autowired
        RetryService retryService;
        @GetMapping("/testRetry")
        public String testRetry(int code) throws Exception {
            int result = retryService.retryTest(code);
            return "result:" + result;
        }
    }
    

    2.4 service测试类(重点)

    /**
     * @description: TODO
     * @author Administrator
     * @date 2021/6/2 12:23
     * @version 1.0
     */
    package com.laowang.springretry.service;
    
    import org.springframework.retry.annotation.Backoff;
    import org.springframework.retry.annotation.Recover;
    import org.springframework.retry.annotation.Retryable;
    import org.springframework.stereotype.Service;
    import java.time.LocalTime;
    
    @Service
    public class RetryServiceImpl implements RetryService {
    
        @Override
        @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
        public int retryTest(int code) throws Exception {
            System.out.println("retryTest被调用,时间:" + LocalTime.now());
            if (code == 0) {
                throw new Exception("异常抛出!");
            }
            System.out.println("retryTest被调用,情况对头了!");
    
            return 200;
        }
        @Recover
        public int recover(Exception e) {
            System.out.println("回调方法执行,可以记录日志到数据库!!!!");
            //记日志到数据库 或者调用其余的方法
            return 400;
        }
    }
    
    

    说明:三个标签

    @Retryable注解
    被注解的方法发生异常时会重试
    value:指定发生的异常进行重试
    include:和value一样,默认空,当exclude也为空时,所有异常都重试
    exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
    maxAttemps:重试次数,默认3
    backoff:重试补偿机制,默认没有

    @Backoff注解说明
    delay:指定延迟后重试
    multiplier:指定延迟的倍数,比如delay=2000,multiplier=1.5时,第二次重试与第一次执行间隔:2秒;第三次重试与第二次重试间隔:3秒;第四次重试与第三次重试间隔:4.5秒。。。

    @Recover
    当重试到达指定次数时,被注解的方法将被回调,可以在该方法中进行日志处理。需要注意的是发生的异常和入参类型一致时才会回调

    2.5 项目启动

    执行运行application,启动成功,默认端口号:8080

    2.6 使用swagger进行验证

    (1)swagger访问地址:

    http://localhost:8080/swagger-ui.html

    (2)先验证成功返回

    先测试正常调用试试,code=1

    调用返回:

    (3)重试机制:code=0(重点)

    为了更好的说明问题,参数配置增大一些:

    @Retryable(value = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 2000, multiplier = 2))
    

    执行效果

    说明:

    从执行效果看,总共执行5次,第二次跟第一次之间是2秒;第三次跟第二次之间是2*2=4秒;第四次与第三次之间是:2 乘以2乘以2=8秒,第五次与第四次之间是:2 乘以2乘以2乘以2=16秒,符合预期。

    执行完成后,进入 @Recover标签内容,可以进行日志记录,以便后续定位问题。

    github项目地址:

    https://github.com/ruanjianlaowang/springretry
    

    更多信息请关注公众号:「软件老王」,关注不迷路,软件老王和他的IT朋友们,分享一些他们的技术见解和生活故事。

    更多信息请关注公众号:「软件老王」,关注不迷路,IT技术与相关干货分享,回复关键字获取对应干货,本文版权归作者软件老王所有,转载需注明作者、超链接,否则保留追究法律责任的权利。
  • 相关阅读:
    “吃神么,买神么”的第一个Sprint计划(第六天)
    “吃神么,买神么”的第一个Sprint计划(第五天)
    “吃神么,买神么”的第一个Sprint计划(第四天)
    “吃神么,买神么”的第一个Sprint计划(第三天)
    “吃神么,买神么”的第一个Sprint计划(第二天)
    Monkey测试简介【转载】
    git diff 理解
    2018 北航软工教学培训小结
    团队项目(2+3):自动测试平台-- 需求文档
    R语言-编写自定义函数 ZZ
  • 原文地址:https://www.cnblogs.com/ruanjianlaowang/p/14868011.html
Copyright © 2020-2023  润新知