Spring Retry方法重试
Spring Retry方法重试
文章目录
- 介绍
- 使用
- 注解方式:@Retryable
- Retryable注解的属性
- Retryable注解的使用
- 模板方式:RetryTemplate
介绍
Spring Retry是Spring框架提供的用于处理重试操作的模块。它旨在简化在应用程序中处理失败和异常情况的重试逻辑。
使用
-
引入依赖
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.3.1</version> </dependency>
-
启用重试
在Spring配置类上添加@EnableRetry注解,启用重试功能。
-
使用重试
- @Retryable注解方式
- RetryTemplate模板方式
注解方式:@Retryable
当使用@Retryable注解的方法在执行时发生异常时,Spring将自动重试该方法,直到方法成功执行或达到最大重试次数。
Retryable注解的属性
-
interceptor
说明:该属性用于指定一个重试拦截器。重试拦截器可以在每次重试之前或之后执行特定操作,例如记录日志、执行某些额外的逻辑等。通过指定拦截器,可以对重试过程进行更精细的控制和扩展。
注意:interceptor属性与其它属性是互斥的。
用途:通常用于实现自定义的重试逻辑、日志记录、性能统计等。
-
value
说明:该属性用于指定触发重试的异常类型。它是一个Class类型的数组,可以指定一个或多个异常类。只有当方法抛出指定类型的异常时,才会触发重试机制。
注意:value与include类型类似,优先级高于include。默认为空(如果exclude排除也为空,则重试所有异常)
用途:用于定义哪些异常应该触发重试策略,可以根据具体业务需求和异常类型进行设置。
-
include
说明:该属性用于指定必须包含在内的异常类型,只有这些异常会触发重试。与value属性相似,但优先级低于value。如果同时指定了include和value,则以value为准。
注意:include与value类型类似,优先级低于include。默认为空(如果exclude排除也为空,则重试所有异常)
用途:在某些情况下,你可能只想对特定的异常进行重试,而不是对所有异常都进行重试。
-
exceptionExpression
说明:该属性是一个SpEL(Spring Expression Language)表达式,用于进一步定义哪些异常应该触发重试。它允许根据异常的详细信息进行更灵活的控制。
用途:用于根据自定义表达式来决定是否进行重试,例如根据异常的特定属性、消息内容等。
-
exclude
说明:该属性用于指定需要排除的异常类型,即使它们匹配了value、include或exceptionExpression指定的条件,也不会触发重试。
注意:如果include为空但exclude不为空,则重试所有未排除的异常。
用途:用于明确排除某些异常,确保它们不会触发重试机制。
-
label
说明:为重试策略提供一个标签。这个标签可以用于日志、监控或其他目的,以区分不同的重试策略。
用途:帮助在多个重试策略中进行标识和区分。
-
stateful
说明:表示该重试是有状态的还是无状态的。默认为false(无状态)。在有状态重试中,每次尝试可能会受之前尝试的影响。
用途:适用于那些前一次尝试的结果会影响下一次尝试的场景。
-
maxAttempts
说明:该属性用于设置最大重试次数(包括第1次调用)。它表示在方法连续失败的情况下,最多可以尝试多少次重试。当达到最大重试次数后,如果方法仍然失败,将不再继续重试。
用途:用于控制重试的次数,避免无限循环重试导致的资源浪费和性能问题。
-
maxAttemptsExpression
说明:与maxAttempts功能类似,但它接受一个SpEL表达式,用于动态地计算最大重试次数。
用途:为最大重试次数提供动态配置能力,根据实际运行时的参数、环境变量等来决定最大重试次数。
-
backoff
说明:该属性用于配置退避策略,即两次连续重试之间的延迟策略等。常见的策略包括固定延迟和指数延迟。属性指定一个@Backoff注解
Backoff注解的属性:
- value:用于指定重试间隔的起始值(默认为 1000 毫秒)。
- delay:用于指定固定的重试间隔(默认为 0)。
- maxDelay:用于指定重试间隔的最大值(默认为 0,表示没有最大间隔限制)。
- multiplier:用于计算下一个重试间隔的倍数(默认为 0,表示不使用指数级增长)。
- maxDelayExpression:用于指定重试间隔的最大表达式,允许你使用 SpEL 表达式动态地计算最大的重试间隔。
- multiplierExpression:用于指定重试间隔的倍数表达式,允许你使用 SpEL 表达式动态地计算重试间隔的倍数。
- random:用于指定是否使用随机间隔时间(默认为 false)。
用途:通过设置合适的退避策略,可以避免频繁的重试对系统造成过大压力,同时合理分散请求,提高系统的可用性和稳定性。
-
listeners
说明:定义重试事件的监听器。这些监听器可以捕获到重试的开始、结束、失败等事件,并据此执行相应的操作。
用途:用于实现自定义的重试事件处理逻辑,如发送通知、记录详细日志等。
Retryable注解的使用
-
定义重试方法:在您希望进行重试的方法上添加@Retryable注解。
@Retryable注解的属性:
- value:指定需要重试的异常类型。可以是单个异常类型或异常类型数组。
- maxAttempts:指定最大重试次数。
- backoff:指定重试间隔和退避策略。
-
定义重试失败处理方法:如果达到最大重试次数但仍然失败,可以使用@Recover注解在另一个方法中定义重试失败的处理逻辑。
@RestController
@RequestMapping(value = "/retry")
public class RetryController {@Autowiredprivate RetryTest retryTest;@GetMapping(value = "testAnnotation")public ApiResult test() {retryTest.test();return ApiUtil.success();}
}
@EnableRetry
@Component
public class RetryTest {@Retryable(value = {Exception.class}, // 指定需要重试的异常类型maxAttempts = 3, // 最大重试次数backoff = @Backoff(delay = 1000, multiplier = 2) // 重试间隔和退避策略)public void test() {System.out.println("RetryTest.test() 调用"+ DateUtil.formatDateTime(new Date()));int i = 1 / 0;}@Recoverpublic void recover(Exception e) {System.out.println("RetryTest.test() 重试仍然失败了");System.out.println(e);}
}
日志
RetryTest.test() 调用2023-11-13 22:17:03
RetryTest.test() 调用2023-11-13 22:17:04
RetryTest.test() 调用2023-11-13 22:17:06
RetryTest.test() 重试仍然失败了
java.lang.ArithmeticException: / by zero
模板方式:RetryTemplate
使用RetryTemplate模板实现重试。
@Configuration
public class RetryTemplateConfig {@Beanpublic RetryTemplate retryTemplate() {RetryTemplate retryTemplate = new RetryTemplate();// 定义重试策略SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();retryPolicy.setMaxAttempts(3); // 最大重试次数retryTemplate.setRetryPolicy(retryPolicy);// 定义重试间隔ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();backOffPolicy.setInitialInterval(1000);backOffPolicy.setMultiplier(2);retryTemplate.setBackOffPolicy(backOffPolicy);return retryTemplate;}
}
@RestController
@RequestMapping(value = "/retry")
public class RetryController {@Autowiredprivate RetryTest retryTest;@Autowiredprivate RetryTemplate retryTemplate;@GetMapping(value = "testAnnotation")public ApiResult test() {retryTest.test();return ApiUtil.success();}@GetMapping(value = "testTemplate")public ApiResult test1() {retryTemplate.execute(retryContext -> {// 业务逻辑System.out.println("RetryTest.test() 调用"+ DateUtil.formatDateTime(new Date()));int i = 1 / 0;return null;},retryContext -> {System.out.println("RetryTest.test() 重试仍然失败了");System.out.println(retryContext.getLastThrowable());return null;});return ApiUtil.success();}
}
日志
RetryTest.test() 调用2023-11-13 22:24:05
RetryTest.test() 调用2023-11-13 22:24:06
RetryTest.test() 调用2023-11-13 22:24:08
RetryTest.test() 重试仍然失败了
java.lang.ArithmeticException: / by zero
- 基于Rabbitmq和Redis的延迟消息实现
- Linux 安全
- MySQL的DATE
- 浪潮服务器安装操作系统
- 机器学习基础之《回归与聚类算法(6)—模型保存与加载》
- Spring Security OAuth2.0 实现分布式系统的认证和授权
- 多平台发布文章产品需求文档
- 电脑桌面图标打不开?三种方法让你轻松应对
- Kotlin之控制语句和表达式
- Linux 性能调优之硬件资源监控
- 如何通过把setTimeout异步转为同步
- 业务出海之服务器探秘
- 利用Python计算每月工资
- SDL2 播放视频数据(YUV420P)
- SpringBoot 自定义参数校验(5)
- matlab导入txt数据
- 【程序基础】动态规划