首页 > 其他分享 >我是如何使用Spring Retry减少1000 行代码

我是如何使用Spring Retry减少1000 行代码

时间:2023-08-22 17:33:11浏览次数:42  
标签:Retry Spring 代码 使用 重试 spring 1000

本文翻译自国外论坛 medium,原文地址:https://levelup.gitconnected.com/how-i-deleted-more-than-1000-lines-of-code-using-spring-retry-9118de29060

使用 Spring Retry 重构代码的综合指南。

问题介绍

在我的日常工作中,我主要负责开发一个庞大的金融应用程序。当客户发送请求时,我们使用他们的用户 ID 从第三方服务获取他们的帐户信息,保存交易并更新缓存中的详细信息。尽管整个流程看起来足够简单,但这些下游系统中的每一个都是不可靠的。我们必须在每一层上实现重试,并且我们必须以一种可以控制重试次数和每次重试之间的延迟的方式来实现,这样我们就不会超载下游系统。由于我无法共享实际代码,我会创建一个演示系统来做简单表示:

由于我们必须在每一层上实现重试,因此我们必须编写大量样板代码,这不仅容易出错,而且难以维护。由于每个下游系统都有自己的重试要求,因此我们最终添加了越来越多的代码,最终就像在现有垃圾之上添加垃圾一样。随着时间的推移,代码变得非常脆弱,即使是很小的变化也会破坏整个系统。

推荐博主开源的 H5 商城项目waynboot-mall,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:https://github.com/wayn111/waynboot-mall

解决方案

为了解决这个问题我们决定使用 Spring Retry。

Spring Retry 项目地址:https://github.com/spring-projects/spring-retry

Spring Retry 是 Spring Batch 的一个子项目,它提供了一组注解和接口,我们可以使用它们向代码添加重试逻辑。它提供了一种向代码添加重试逻辑的声明性方法。

作为本文的一部分,我们将了解如何使用 Spring Retry 重写现有代码,以及它如何帮助我将代码库减少 1000 行。在展示新代码时,我将解释每个代码的注解和用例。

在研究重构的代码之前,让我们先了解一下在项目中设置 Spring 重试所涉及的步骤。

Let’s start hacking!

1. 设置 Spring 重试

将以下依赖项添加到我们的 pom.xml 文件中:

<dependency>
   <groupId>org.springframework.retry</groupId>
   <artifactId>spring-retry</artifactId>
   <version>2.0.0</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aspects</artifactId>
   <version>5.2.8.RELEASE</version>
</dependency>
  1. 在 spring 配置上启用 Spring 重试,并使用以下注解:
@Configuration
@EnableRetry
public class ApplicationConfig { }

2. 重构代码

既然我们已经设置了 Spring Retry,那么让我们开始重构代码。

  1. 以下是一个查询用户全名的代码示例,左边是老代码,右边是使用了 Spring Retry 的新代码。

使用 @Retryable 注解,我们通过 retryFor 属性指定要重试的异常数组,使用 maxAttempts 属性,可以指定要重试的次数。

  1. 具有指数退避的缓存重试

一下图片是一个添加缓存的代码示例中,我指定要在 JedisConnectionException 上重试,每次重试之间的延迟应为 1000 毫秒,并且延迟应呈指数增长。

使用 @Retryable 注解,我们可以使用重试退避 backoff 属性,还可以指定每次重试之间的延迟 delay。

  1. 外部化重试配置

我们可以轻松地将重试配置外部化到属性文件中。当我们想要重用配置并更改它们而无需重新部署应用程序时,这非常有用。就我而言,我创建了一个 retry.properties 文件并添加了以下属性:

retry.maxAttempts=2

在我的 spring 配置中包含属性文件:

// <<Other annotations>>
@PropertySource("classpath:retryConfig.properties")
public class ApplicationConfig { }

以下图片是一个先获取 MySql 连接,再查数据的例子,我再代码中使用了该外部化配置属性:

  1. 消除错误时的重复操作,使用 RetryListenerSupport 重试

在前面的先获取 MySql 连接,再查数据的例子中,我想获取以下事件的指标:

  • 连接 MySql 数据库时,发出指标
  • 连接 MySql 数据库失败时,发出指标
  • 当用尽所有重试次数时,发出指标

再 Spring Retry 中,我可以使用 RetryListenerSupport 将所有代码添加到一个位置,而不是在连接到 Mysql 数据库的所有代码的每个重试块中添加相同的代码。

使用 RetryTemplate 上的 registerListener 方法注册 RetryListenerSupport:

@Configuration
public class ApplicationConfig {

  @Bean
  public RetryTemplate installTemplate() {
     RetryTemplate retryTemplate = new RetryTemplate();
     retryTemplate.registerListener(new DefaultListenerSupport());
     return retryTemplate;
  }
}

RetryListenerSupport 提供了三种方法,我们可以重写它们来添加自定义逻辑:

  • onError — 当出现错误时调用此方法
  • close——当所有重试都用尽时调用该方法
  • open — 重试开始时调用该方法

现在让我们看看重构后的代码:

总结

在本文中,我们了解了如何使用 Spring Retry 来减少样板代码并使代码更具可读性和可维护性。通过 Spring Retry,相信你也能够消除超过 1000 行代码。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

标签:Retry,Spring,代码,使用,重试,spring,1000
From: https://www.cnblogs.com/waynaqua/p/17649196.html

相关文章

  • spring-boot-starter
    springboot在配置上相比spring要简单很多,其核心在于spring-boot-starter,在使用springboot来搭建一个项目时,只需要引入官方提供的starter,就可以直接使用,免去了各种配置。starter简单来讲就是引入了一些相关依赖和一些初始化的配置命名规范:官方的starter:spring-boot-start......
  • SpringCloud
    SpringCloud服务开发注意事项:不同微服务,不开发相同业务2.微服务数据独立,不问其他微服务数据库3.微服务将自己的业务接口暴露为借口,供其他微服务调用提供者与消费者提供者:一次业务中被其他微服务调用的服务(提供接口给其他)消费者:一次业务中调用其他微服务的服务(调用其他......
  • 2023-08-22:请用go语言编写。给定一个长度为N的正数数组,还有一个正数K, 返回有多少子序
    2023-08-22:请用go语言编写。给定一个长度为N的正数数组,还有一个正数K,返回有多少子序列的最大公约数为K。结果可能很大,对1000000007取模。1<=N<=10^5,1<=arr[i]<=10^5。来自腾讯笔试。来自左程云。答案2023-08-22:算法过程分步描述如下:1.初始化数组dp、cnt和pow2,长度为MAX......
  • 中小学教育综合管理平台源码,vue2+Java+springboot框架开发
    智慧校园电子班牌软件是出于校园考勤管理以及班级校园信息展示为目的的显示系统软件,电子班牌系统主要用于中小学教育的综合管理平台,融合了多媒体技术、语音技术、人脸识别、信息发布、后台管理等多种技术。智慧班牌通过以云平台为基础,结合互联网、物联网系统进行校园管理,实现学校数......
  • SpringBoot实现统一异常处理
    大家在使用SpringBoot开发项目的时候肯定都需要处理异常吧,没有处理异常那么异常信息直接显示给用户这是非常不雅观的,同时还可能造成用户误会,那么今天我们就来简单的写一下如何在SpringBoot项目中实现统一的异常处理。1.自定义异常类我们先定义一个自定义业务异常类,这个异常类继......
  • 基于springboot课程答疑系统
    随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势,针对这个问题开发一个专门适应师生交流形式的网站。本文介绍了课程答疑系统的开发全过程。通过分析企业对于课程答疑系统的需求,创建了一个计算机管理课程答疑系统的方案。文章介绍了课程答疑系统的系统分析部分,包括可行性分析......
  • 基于springboot师生共评的作业管理系统设计与实现
    随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势,针对这个问题开发一个专门适应师生作业交流形式的网站。本文介绍了师生共评的作业管理系统的开发全过程。通过分析企业对于师生共评的作业管理系统的需求,创建了一个计算机管理师生共评的作业管理系统的方案。文章介绍了师生共......
  • springSecurity异常提示国际化
    1:获取国际化文件在一个jar包里,可以先下载jar包,然后再里面找到中文的那个文件<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>3.2.0.RELEASE</vers......
  • SpringBoot内嵌Tomcat连接池分析
    目录1Tomcat连接池1.1简介1.2架构图1.2.1JDK线程池架构图1.2.2Tomcat线程架构1.3核心参数1.3.1AcceptCount1.3.2MaxConnections1.3.3MinSpareThread/MaxThread1.3.4MaxKeepAliveRequests1.3.5ConnectionTimeout1.3.6KeepAliveTimeout1.4核心内部线程1.4.1Acceptor1.......
  • SpringBoot 测试实践 - 2:单元测试与集成测试
    单元测试vs.集成测试只编写单测,无法测试方法之间的集成情况,而且某些需求可能会修改多个方法,这可能会影响方法对应的单测,涉及到大量的相关单测的修改,这样的维护成本很高可以把重心放在完善集成测试上,专注从外部判断程序是否符合预期。对于一些非常重要的方法,增加单元测试可以减......