springboot整合spring-retry的实现示例

 更新时间:2021年06月11日 14:08:06   作者:软件老王  
本文将结合实例代码,介绍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

到此这篇关于springboot整合spring-retry的实现示例的文章就介绍到这了,更多相关springboot整合spring-retry内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot跨域Jsonp和Cors的方法

    SpringBoot跨域Jsonp和Cors的方法

    这篇文章主要介绍了SpringBoot跨域Jsonp和Cors的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java InputStream的多种使用详解

    Java InputStream的多种使用详解

    这篇文章主要介绍了Java InputStream的多种使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • java实现微信公众号消息推送的方法详解

    java实现微信公众号消息推送的方法详解

    这篇文章主要为大家详细介绍了如何利用java实现微信公众号消息推送的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • 使用JWT创建解析令牌及RSA非对称加密详解

    使用JWT创建解析令牌及RSA非对称加密详解

    这篇文章主要介绍了JWT创建解析令牌及RSA非对称加密详解,JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌,一种情况是webapi,类似之前的阿里云播放凭证的功能,另一种情况是多web服务器下实现无状态分布式身份验证,需要的朋友可以参考下
    2023-11-11
  • 多线程如何解决for循环效率的问题

    多线程如何解决for循环效率的问题

    这篇文章主要介绍了多线程如何解决for循环效率的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 解决@Autowired注入空指针问题(利用Bean的生命周期)

    解决@Autowired注入空指针问题(利用Bean的生命周期)

    这篇文章主要介绍了解决@Autowired注入空指针问题(利用Bean的生命周期),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Spring Boot多数据源及其事务管理配置方法

    Spring Boot多数据源及其事务管理配置方法

    本篇文章主要介绍了Spring Boot多数据源及其事务管理配置方法,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • Java打印数组的三种方法整理

    Java打印数组的三种方法整理

    许多学编程专业的同学面试的时候,考官都会问到Java如何打印数组这样的问题,下面这篇文章主要给大家介绍了关于Java打印数组的三种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • Java中数组array和列表list相互转换

    Java中数组array和列表list相互转换

    这篇文章主要介绍了Java中数组array和列表list相互转换,在Java中,可以将数组(array)和列表(list)相互转换,但需要注意一些细节和限制,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • 深入了解Java设计模式之UML类图

    深入了解Java设计模式之UML类图

    UML 即 Unified Modeling Language 统一建模语言,是用来设计软件的可视化建模语言。本文就带大家了解一下UML中类图的定义与使用,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-11-11

最新评论