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 {@AutowiredRetryService 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;}@Recoverpublic 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朋友们,分享一些他们的技术见解和生活故事。

基于springboot整合spring-retry相关推荐

  1. 八、springboot整合Spring Security

    springboot整合Spring Security 简介 Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架.它是保护基于Spring的应用程序的事实标准. Spr ...

  2. springboot整合spring @Cache和Redis

    转载自  springboot整合spring @Cache和Redis spring基于注解的缓存 对于缓存声明,spring的缓存提供了一组java注解: @Cacheable:触发缓存写入. @ ...

  3. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离

    在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与权限管理. ...

  4. springBoot整合spring security+JWT实现单点登录与权限管理前后端分离--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  5. SpringBoot整合Spring Data Elasticsearch

    特点: 分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心) Restful风格,一切API都遵循Rest原则,容易上手 近实时搜索,数据更新在Elasticsear ...

  6. SpringBoot 整合 Spring Security 实现安全认证【SpringBoot系列9】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见. 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCl ...

  7. SpringBoot整合Spring Security【超详细教程】

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/Lee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 Spring Security是一个 ...

  8. 基于Springboot整合RestTemplate调用Webservice接口

    1.基于Springboot整合RestTemplate调用Webservice接口,如果感觉使用webservice客户端调用服务器端不会,或者不方便 的时候,可以尝试使用RestTemplate来 ...

  9. springboot整合spring Cache(redis)

    前言 前面有介绍过spring整合redis和redis的一些注意点,在实际开发中,spring cache方便简化的缓存操作的大部分内容.通过注解的方式实现缓存. 阅读前推荐先阅读:redis缓存介 ...

最新文章

  1. 赠票 | 互联网大厂的数据治理与资产管理实战 | DAMS 2020
  2. LinFu Dynamic Proxy - LinFu 2.3, LinFu.DynamicProxy 1.031
  3. 转:csdn怎么快速转载别人的文章
  4. DNS 截持模拟及环境搭建
  5. docker下载慢,卡顿解决办法——免费安装人人都有的docker加速器
  6. owin 怎么部署在云中_使用Boxfuse轻松在云中运行Spring Boot应用程序
  7. 线性代数【15】复合线性变换-矩阵乘法 和 三维变换
  8. 如何加入github开源项目!
  9. android 打开设备失败
  10. mysql load data 一行_MySQL LOAD DATA LOCAL INFILE仅导入一行
  11. Winform使用FTP实现自动更新
  12. 学习日志-《微习惯》心得
  13. android中AudioRecord使用详解
  14. 一台机器(群晖、CentOS)挂两台网心云docker
  15. Python模块pathlib
  16. 羊城杯2022--Writeup
  17. 蓝鲸智云实现虚拟机交付(四)-配置平台自定义(CMDB)
  18. 血战力扣752.打开转盘锁
  19. linux版本市场占有率,2020年5月OS市场占有率报告:Ubuntu和Linux分别占有1.89%和0.97%...
  20. Vundle(Vim bundle) 是一个vim的插件管理器。

热门文章

  1. 赵强老师:Oracle数据库系列课程(20)优化数据库-赵强老师-专题视频课程
  2. html css data-,HTML+CSS入门 HTML自定义data属性详解
  3. Python每日一练19、简单的加减法数学游戏
  4. 中体彩软件研发笔试题
  5. 使用telnet命令模拟发送邮件
  6. .net 继续学习引领
  7. jquery的$是什么意思?
  8. TypeORM vs Prisma
  9. java sdn_Java实现SDN拓扑获取
  10. 网站数据采集-网站采集工具-SEO文章聚合采集(免费采集教程)