Spring Retry 和 Guava Retrying重试机制的使用详解

点击下载《Spring Retry 和 Guava Retrying重试机制的使用详解》

1. Spring-Retry优雅地实现重试机制

在现代的分布式系统中,由于网络不稳定、服务短暂不可用或资源争用等原因,调用远程服务时偶尔会遇到失败。为了增强系统的健壮性,我们通常会在遇到这类失败时进行重试。Spring-Retry是一个用于Spring应用的库,它提供了声明式的重试机制,让开发者能够以非常简单的方式实现重试逻辑。

1.1 基本使用

Spring-Retry的使用非常直观。首先,你需要在项目中添加Spring-Retry的依赖。然后,你可以通过在需要重试的方法上添加@Retryable注解来声明这个方法在失败时应该被重试。你还可以指定重试的策略,比如最大重试次数、重试间隔等。

添加依赖

<!-- Spring Retry库本身 -->
<dependency>  <groupId>org.springframework.retry</groupId>  <artifactId>spring-retry</artifactId>  <version>1.2.5.RELEASE</version>  
</dependency>
<!-- Spring AOP库 -->
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-aspects</artifactId>  <version>5.2.8.RELEASE</version>  
</dependency>
<!-- Spring Core Container Libraries -->
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context</artifactId>  <version>5.2.8.RELEASE</version>  
</dependency>

下面是一个简单的例子:

@Service  
public class MyService {  @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000))  public void retryService() {  // 模拟业务逻辑,可能会抛出异常  System.out.println("执行业务逻辑...");  throw new RuntimeException("业务逻辑异常");  }  @Recover  public void recover(Exception e) {  System.out.println("重试失败后执行恢复操作...");  }  
}

在这个例子中,retryService方法被标记为可重试的。如果这个方法抛出Exception类型的异常,Spring-Retry会捕获这个异常,并按照指定的策略进行重试。maxAttempts属性指定了最大重试次数,backoff属性指定了重试间隔的策略。如果所有的重试都失败了,那么recover方法会被调用,你可以在这个方法中执行一些恢复操作。

1.2 重试策略

Spring-Retry支持多种重试策略,包括固定间隔、指数回退等。你可以通过@Backoff注解来指定重试间隔的策略。例如,你可以使用@ExponentialBackoff注解来实现指数回退的重试策略。

1.3 异步重试

Spring-Retry还支持异步重试。你可以通过将@Retryable注解的async属性设置为true来开启异步重试。需要注意的是,开启异步重试后,重试的方法需要返回一个Future对象。

1.4 优点与缺点

Spring-Retry的主要优点是它提供了声明式的重试机制,让开发者能够非常简单地实现重试逻辑。此外,它还支持多种重试策略和异步重试,非常灵活。

然而,Spring-Retry也有一些缺点。首先,它依赖于Spring框架,如果你的项目没有使用Spring,那么你可能无法使用Spring-Retry。其次,Spring-Retry的重试逻辑是在运行时通过AOP实现的,这可能会引入一些性能开销。

1.5 使用场景

Spring-Retry适用于需要实现重试逻辑的Spring应用。它特别适合用于调用远程服务或执行可能会失败的操作的场景。例如,你可以使用Spring-Retry来实现对RESTful API的调用、对数据库的访问或对其他外部系统的集成。

总之,Spring-Retry是一个非常实用的库,它让开发者能够以非常简单的方式实现重试逻辑,增强系统的健壮性。如果你正在开发一个Spring应用,并且需要实现重试逻辑,那么不妨考虑使用Spring-Retry。

2. Guava-Retry灵活且强大的重试机制库

在分布式系统和网络应用中,由于各种原因(如网络波动、服务暂时不可用等),我们经常会遇到需要重试的场景。重试机制是增强系统鲁棒性的一种有效手段。Guava-Retry是一个基于Google Guava库的扩展,它提供了灵活且强大的重试功能,让开发者能够轻松地为自己的方法实现重试逻辑。

2.1 基本使用

Guava-Retry并不是Guava官方的一部分,而是一个第三方库,通常称为guava-retrying。要使用Guava-Retry,首先需要将其添加到项目的依赖中。然后,你可以使用Retryer类来定义重试策略并执行重试。

添加依赖

<!-- guava-retrying dependency -->  
<dependency>  <groupId>com.github.rholder</groupId>  <artifactId>guava-retrying</artifactId>  <version>3.0.7</version> <!-- 请注意版本号,根据需要使用最新版本 -->  
</dependency>  
<!-- Guava dependency, 虽然guava-retrying自带了所需的Guava部分,但有时候可能需要显式添加Guava依赖以确保版本兼容性 -->  
<dependency>  <groupId>com.google.guava</groupId>  <artifactId>guava</artifactId>  <version>30.1-jre</version> <!-- 请使用与您的项目兼容的版本 -->  
</dependency>  

下面是一个简单的使用示例:

import com.github.rholder.retry.Attempt;  
import com.github.rholder.retry.Retryer;  
import com.github.rholder.retry.RetryerBuilder;  
import com.github.rholder.retry.StopStrategies;  
import com.github.rholder.retry.WaitStrategies;  public class GuavaRetryExample {  public static void main(String[] args) {  Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()  .retryIfExceptionOfType(RuntimeException.class) // 只在抛出RuntimeException时重试  .retryIfResult(result -> result == null) // 如果结果为null也重试  .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 最大重试次数为3  .withWaitStrategy(WaitStrategies.fixedWait(1000, TimeUnit.MILLISECONDS)) // 重试间隔为1秒  .build();  try {  retryer.call(() -> {  // 模拟可能失败的业务逻辑  System.out.println("执行可能失败的操作...");  throw new RuntimeException("操作失败");  // 如果操作成功,应返回相应的结果,如:return true;  });  } catch (ExecutionException | RetryException e) {  System.err.println("重试失败: " + e.getMessage());  }  }  
}

在上面的例子中,我们创建了一个Retryer实例,并定义了重试的条件和策略。然后,我们通过call方法执行可能会失败的操作。如果操作失败并且满足重试条件,Retryer会自动进行重试,直到达到最大重试次数或操作成功为止。

2.2 重试策略与等待策略

Guava-Retry允许你定义灵活的重试策略和等待策略。重试策略决定了在哪些情况下应该进行重试,而等待策略则决定了每次重试之间的等待时间。

2.3 优缺点

优点:

  1. 灵活性:Guava-Retry提供了丰富的配置选项,可以根据具体需求定制重试策略和等待策略。
  2. 易用性:通过简单的API调用,就可以轻松地为方法添加重试逻辑。
  3. 扩展性:可以自定义重试条件和等待策略,以满足更复杂的需求。

缺点:

  1. 额外依赖:虽然Guava是一个非常流行的Java库,但Guava-Retry作为第三方扩展,需要额外添加到项目的依赖中。
  2. 学习成本:对于不熟悉Guava或重试机制的开发者来说,可能需要一些时间来学习和理解Guava-Retry的用法和配置。

2.4 使用场景

Guava-Retry适用于任何需要实现重试逻辑的Java应用。以下是一些典型的使用场景:

  1. 远程服务调用:当调用远程服务(如REST API、RPC服务)时,由于网络不稳定或服务暂时不可用,可以使用Guava-Retry进行重试,以提高调用的成功率。
  2. 数据库操作:在执行数据库操作时,如果遇到死锁、超时或其他可重试的错误,可以使用Guava-Retry进行重试。
  3. 文件操作:在进行文件读写操作时,如果由于文件被占用或其他原因导致操作失败,可以使用Guava-Retry进行重试。

3. 总结

Spring Retry 和 Guava Retrying 都是用于实现重试机制的库,它们在功能和用法上有所相似,但也存在一些差异。

  1. 依赖关系
    • Spring Retry:作为 Spring 框架的一部分,使用 Spring Retry 需要引入 Spring 相关依赖。
    • Guava Retrying:作为 Google Guava 库的一部分,使用 Guava Retrying 需要引入 Guava 相关依赖。
  2. 注解方式
    • Spring Retry:提供了一组注解(如 @Retryable@Recover 等),使得在 Spring 组件方法上标注重试逻辑变得简单直观。
    • Guava Retrying:也提供了一组注解(如 @Retry@UncheckedIOException 等),但相对于 Spring Retry,Guava Retrying 的注解使用上可能稍显复杂。
  3. 回退策略
    • Spring Retry:提供了多种内置的回退策略,如线性回退、指数回退等,也可以通过自定义实现回退策略接口来自定义回退逻辑。
    • Guava Retrying:同样支持多种回退策略,但相比之下,Guava Retrying 的回退策略更加灵活,提供了更多的配置选项。
  4. 异常处理
    • Spring Retry:支持根据异常类型进行重试判断,可以自定义需要重试或排除的异常类型。
    • Guava Retrying:同样可以根据异常类型进行重试判断,但异常处理方面的配置相对较少。
  5. 线程池使用
    • Spring Retry:不直接支持线程池的使用,需要结合其他工具或库来实现多线程重试。
    • Guava Retrying:提供了一个与线程池结合使用的示例,使得在多线程环境下实现重试更加方便。
  6. API 文档和社区支持
    • Spring Retry:作为 Spring 框架的一部分,有丰富的文档和社区支持。
    • Guava Retrying:虽然 Guava 库本身具有广泛的文档和社区支持,但相对于 Spring Retry,Guava Retrying 的文档和社区支持可能稍显不足。
  7. 性能和资源消耗
    • Spring Retry:通常来说,Spring Retry 的性能和资源消耗相对较低,但在某些复杂场景下可能会存在一定的性能开销。
    • Guava Retrying:在性能和资源消耗方面表现良好,适用于各种规模的应用程序。

总结:Spring Retry 和 Guava Retrying 都是用于实现重试机制的优秀工具。根据项目需求和个人偏好,可以选择更适合的重试库。如果项目已经使用了 Spring 框架,那么 Spring Retry 可能是一个更好的选择;而如果更看重性能和资源消耗,或者在多线程环境下实现重试,那么 Guava Retrying 可能更合适。

点击下载《Spring Retry 和 Guava Retrying重试机制的使用详解》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/649811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习--基础概念(二)

1.分类算法 分类算法是有监督学习的一个核心问题&#xff0c;他从数据中学习一个分类决策函数或分类模型&#xff0c;对新的输入进行预测&#xff0c;输出变量取有限个离散值。 以下是一些常见的分类算法&#xff1a; 逻辑回归 (Logistic Regression): 用于二分类问题&#x…

项目风采展示【TRDa】

桌面功能介绍&#xff1a; 1&#xff1a;支持本地音乐、三方音乐控制播放展示功能&#xff1b; 2&#xff1a;支持陀螺仪 3&#xff1a;支持蓝牙列表显示。

STM32单片机的基本原理与应用(二)

单片机外部中断的基本原理 STM32 的每个 IO 都可以作为外部中断的中断输入口&#xff0c;这点也是 STM32 的强大之处。那么其中断是怎样实现的呢&#xff1f;其原理就是由GPIO口产生触发信号&#xff0c;通过NVIC中断控制器和EXTI外部中断控制器完成中断响应。使用外部中断可以…

Node.js Cool 框架分页数据 如果在一个状态下获取多个状态的数据

1.需求 比如你想实现 订单状态列表的获取 有可能orderStatus12 的时候 想返回 orderStatus10 11 12 13 的时候 分页返回 2.解决 query.orderProgress[] 此时条件就变成了一个数组 //订单列表async getOrderListByprogress(query) {const { userId } this.ctx.clientInfo…

RabbitMQ问题总结

:::info 使用场景 异步发送&#xff08;验证码、短信、邮件。。。&#xff09;MySQL 和 Redis、ES 之间的数据同步分布式事务削峰填谷… ::: 如何保证消息不丢失 上图是消息正常发送的一个过程&#xff0c;那在哪个环节中消息容易丢失&#xff1f;在哪一个环节都可能丢失 生…

opencv#32 可分离滤波

滤波的可分离性 就是将一个线性滤波变成多个线性滤波&#xff0c;这里面具体所指的是变成x方向的线性滤波和y方向的线性滤波。无论先做x方向的滤波还是y方向滤波&#xff0c;两者的叠加结果是一致的&#xff0c;这个性质取决于滤波操作是并行的&#xff0c;也就是每一个图像在滤…

vue3+echarts绘制某省区县地图

vue3echarts绘制某省区县地图 工作中经常需要画各种各样的图&#xff0c;echarts是使用最多的工具&#xff0c;接近春节&#xff0c;想把之前画的echarts图做一个整合&#xff0c;方便同事和自己随时使用&#xff0c;因此用vue3专门写了个web项目&#xff0c;考虑之后不断完善…

基于SpringBoot实现策略模式提供系统接口扩展能力

相信我们对策略模式都有耳闻&#xff0c;但是可能不知道它在项目中具体能有什么作用&#xff0c;我们需要在什么场景下才能去尽可能得去使用策略模式。 这里我简单的列出一个我之前在公司做的一个需求&#xff1a;跟第三方oa系统对接接口&#xff0c;对方需要回调我们当前系统…

R12.2 EBS 修改 APPS 密码 详细步骤

目录 前言准备修改步骤1.关闭应用层2.FNDCPASS 修改密码3. 运行 autoconfig4.单独启动 webLogic 服务5.登录weblogic&#xff0c;更新apps密码6.启动应用层7.验证 结尾 前言 本文的目的是修改 apps 密码&#xff0c;主要参考官方文档 metalink 1674462.1&#xff0c;请注意本文…

代码随想录算法训练营Day|层序遍历,翻转二叉树,对称二叉树

层序遍历 层序遍历一个二叉树&#xff0c;就是从左往右一层一层的遍历二叉树&#xff0c;这种遍历方式需要借用一个辅助数据结构即队列来实现&#xff0c;队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。而…

Task04:DDPG、TD3算法

本篇博客是本人参加Datawhale组队学习第四次任务的笔记 【教程地址】https://github.com/datawhalechina/joyrl-book 【强化学习库JoyRL】https://github.com/datawhalechina/joyrl/tree/main 【JoyRL开发周报】 https://datawhale.feishu.cn/docx/OM8fdsNl0o5omoxB5nXcyzsInGe…

Delphi 7 IdHTTP POST 中文乱码得解决

WEB后台使用UTF-8进行编码&#xff0c;由于D7默认是ansiString&#xff0c;直接提交到后台会使中文乱码。 解决方法&#xff1a; 1.先把AnsiString转WideString 2.通过System单元中的ansitoUTF8()函数进行转换之后再提交就可以了。 代码示例&#xff1a; procedure postDe…

华为三层交换机之基本操作

Telnet简介 Telnet是一个应用层协议,可以在Internet上或局域网上使用。它提供了基于文本的远程终端接口&#xff0c;允许用户在本地计算机上登录到远程计算机&#xff0c;然后像在本地计算机上一样使用远程计算机的资源。Telnet客户端和服务器之间的通信是通过Telnet协议进行的…

OpenAI 降低价格并修复拒绝工作的“懒惰”GPT-4,另外ChatGPT 新增了两个小功能

OpenAI降低了GPT-3.5 Turbo模型的API访问价格&#xff0c;输入和输出价格分别降低了50%和25%。这对于使用API进行文本密集型应用程序的用户来说是一个好消息。 OpenAI官网&#xff1a;OpenAI AIGC专区&#xff1a;aigc 教程专区&#xff1a;AI绘画&#xff0c;AI视频&#x…

Vite+Electron快速构建一个VUE3桌面应用(二)——动态模块热重载

一. 简介 在上一篇文章ViteElectron快速构建一个VUE3桌面应用中&#xff0c;我们了解了如何使用Vite和Electron来快速构建一个Vue3桌面应用。但是&#xff0c;之前构建的应用仅仅是一个简单的版本。在开发过程中&#xff0c;为了更好的开发体验&#xff0c;在开发electron的时…

博弈论(牛客练习赛)

思路&#xff1a;我们考虑小念赢 1、如果n>1并且p0&#xff0c;小念可以连续取两次&#xff0c;相当于小念有挂&#xff0c;可以从必败态转为必胜态&#xff0c;必赢。 2、如果n>1并且m>n-1&#xff0c;小念第一次取n-1个&#xff0c;小念必赢。 代码&#xff1a; …

【C语言】(1)初识C语言

什么是C语言 C语言是一种广泛应用的计算机编程语言&#xff0c;它具有强大的功能和灵活性&#xff0c;使其成为系统编程和底层开发的首选语言。C语言的设计简洁、高效&#xff0c;且不依赖于特定的硬件或系统&#xff0c;因此在各种计算平台上都能稳定运行。 C语言的特点 高…

C++ 之LeetCode刷题记录(十九)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 开始cpp刷题之旅。 依旧是追求耗时0s的一天。 108. 将有序数组转换为二叉搜索树 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你…

针对于vue element-plus组件的el-date-picker日期区间组件的日期格式问题以及如何进行区间判断

<template><el-date-picker v-model"value1" type"daterange" range-separator"To" start-placeholder"开始日期" end-placeholder"结束日期" :size"size" change"sarend" /> </templat…

速盾:海外网站CDN加速建站有哪些优势?

随着互联网的发展&#xff0c;海外网站的建设和访问需求也日益增加。而为了提高海外网站的访问速度和用户体验&#xff0c;CDN加速技术成为了一种必不可少的解决方案。本文将介绍海外网站CDN加速建站的优势&#xff0c;并回答一些相关问题。 一、提高网站访问速度 海外网站部署…