springboot整合spring-retry的实现示例

作者:软件老王 时间:2022-01-13 01:25:53 

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 项目启动

springboot整合spring-retry的实现示例

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

springboot整合spring-retry的实现示例

2.6 使用swagger进行验证

(1)swagger访问地址:

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

(2)先验证成功返回

springboot整合spring-retry的实现示例

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

springboot整合spring-retry的实现示例

调用返回:

springboot整合spring-retry的实现示例

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

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


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

执行效果

springboot整合spring-retry的实现示例

说明:

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

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

github项目地址:https://github.com/ruanjianlaowang/springretry

来源:https://blog.csdn.net/wjg8209/article/details/117751194

标签:springboot,整合,spring-retry
0
投稿

猜你喜欢

  • SpringMVC执行步骤、Model的使用详解

    2022-02-13 05:38:45
  • 基于swing实现窗体拖拽和拉伸

    2023-11-12 22:32:40
  • SpringBoot 自定义starter yaml提示失效问题及解决方法

    2022-08-03 14:58:42
  • 一文探索Java文件读写更高效方式

    2021-12-20 08:31:22
  • C# using三种使用方法

    2023-05-02 20:18:47
  • Java中i++的一些问题总结

    2022-04-11 18:07:34
  • IntelliJ IDEA本地代码覆盖后恢复原来的代码图解

    2022-03-09 22:42:19
  • 详解J2EE开发的网站部署到阿里云服务器的方法

    2022-06-21 07:50:16
  • 浅谈Springboot下引入mybatis遇到的坑点

    2023-09-09 05:55:09
  • java web个人通讯录系统设计

    2022-09-14 11:12:15
  • SpringBoot异步调用方法并接收返回值

    2023-08-16 22:33:49
  • 关于C#连接SQL Server时提示用户登录失败的解决方法

    2021-10-03 21:21:58
  • Java数组(Array)最全汇总(中篇)

    2022-09-05 06:01:02
  • java 实现文件夹的拷贝实例代码

    2023-01-04 10:19:28
  • SpringCache框架加载/拦截原理详解

    2023-04-11 10:31:46
  • 浅谈Java中Collections.sort对List排序的两种方法

    2021-11-18 11:20:22
  • 聊聊SpringMVC项目依赖和静态资源导出问题

    2023-03-26 13:32:20
  • java使用hadoop实现关联商品统计

    2022-11-05 05:55:43
  • 详解解密Java中的类型转换问题

    2023-11-24 20:46:28
  • C#中循环语句:while、for、foreach的使用

    2022-05-01 02:42:55
  • asp之家 软件编程 m.aspxhome.com