【SpringBoot框架篇】34.使用Spring Retry完成任务的重试

文章目录

  • 简要
  • 1.为什么需要重试?
  • 2.添加maven依赖
  • 3.使用@Retryable注解实现重试
  • 4.基于RetryTemplate模板实现重试

简要

Spring实现了一套重试机制,功能简单实用。Spring Retry是从Spring Batch独立出来的一个功能,已经广泛应用于Spring Batch,Spring Integration, Spring for Apache Hadoop等Spring项目。

本文将讲述如何使用Spring Retry及其实现原理。

1.为什么需要重试?

在调用一些第三方接口时候可能会因为网络或者服务方异常导致请求失败,这个时候可以通过重试解决这种问题。

以下面的简单的例子来了解 Retry的功能,下面有个doTask函数,执行该函数的时候如果出现异常则需要重试任务

  • 1.CountDownLatch 用于在主线程用于等待线程池中的任务完成
  • 2.AtomicInteger 类型用于计算重试次数
  • 3.ScheduledExecutorService用于定时执行需要重试的任务,如果没有异常则第一次执行完任务则会关闭线程池
  • 4.doTask函数中通过 1/0故意造成异常
    public static boolean doTask() {try {System.out.println(1/0);return true;} catch (Exception e) {return false;}}/*** 通过ScheduledExecutor定时器实现低配版本的重试机制* @param args* @throws Exception*/public static void main(String[] args) throws Exception {CountDownLatch countDownLatch = new CountDownLatch(1);AtomicInteger count = new AtomicInteger(0);//设置重试的次数int retryNumber = 3;//创建单线程的定时任务处理器ScheduledExecutorService scheduledThreadPool = Executors.newSingleThreadScheduledExecutor();//(参数1=执行内容,参数2=初始延迟时间,参数3=任务间隔时间,参数4=时间单位)scheduledThreadPool.scheduleAtFixedRate(() -> {boolean flag = doTask();//业务是否处理成功,成功则关闭线程池if (flag || count.get() == retryNumber) {//执行成功或者已达到执行次数则关闭线程池scheduledThreadPool.shutdownNow();countDownLatch.countDown();;}else{log.info("第{}次重试任务", count.get()+1);count.getAndIncrement();}}, 0, 1, TimeUnit.SECONDS);//等待线程池中的任务完成countDownLatch.await();}

在这里插入图片描述
把doTask函数中的导致异常的代码注释再运行可以看到控制台没有打印重试的信息

从上面代码可以看出写一个任务重试的工具不难,感兴趣的同学可以通过AOP代理的方式自己实现基于注解的重试功能,Spring官方的Retry模块里有通过Aop加注解的方式实现重试功能,Aop玩腻了,我就不造轮子了。。

2.添加maven依赖

由于retry依赖中没有包含aspectj相关依赖,所以需要单独引用aspectj

    <!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry --><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId><version>1.3.4</version></dependency><!--aop切面--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

3.使用@Retryable注解实现重试

3.1.需要在springboot启动添加@EnableRetry注解开启对Retry的支持

@EnableRetry
@SpringBootApplication
public class RetryApplication {
}

3.2.定义需要重试任务的异常类型

public class CustomRecoveryException extends Exception{public CustomRecoveryException(String error){super(error);}
}

3.3.在需要任务重试的函数上面添加注解

  • value属性表示在哪些异常的情况下才会去重试,多个类型用,隔开。
  • maxAttempts属性设置执行次数,默认值为3则表示异常后只会重试两次
  • backoff属性设置下次重试的延迟时间,默认值为1000ms(1秒)。
@Slf4j
@Service
public class RetryServer  {@Retryable(value = {CustomRecoveryException.class, IOException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))public void retryTest() throws CustomRecoveryException {log.info("retryTest,当前时间:{}",LocalDateTime.now());throw new CustomRecoveryException("test retry error");}

3.4.通过@Recover定义降级处理的函数
返回值需要和重试的任务一致,要不然会抛出异常。

    @Recoverpublic void fallback(Throwable throwable) {// 降级处理逻辑log.error("fallback,Error msg:{}",throwable.getMessage());return "fallback";}} 

3.5.使用junit进行测试

@SpringBootTest
class RetryApplicationTests {@Autowiredprivate RetryServer retryServer;@Testvoid contextLoads() throws CustomRecoveryException {retryServer.retryTest();}
}    

可以看到控制台只打印了三次日志,从这能确认任务共执行了三次,只重试了两次。
在这里插入图片描述

4.基于RetryTemplate模板实现重试

4.1.配置RetryTemplate重试的策略

@EnableRetry
@SpringBootApplication
public class RetryApplication {public static void main(String[] args) {SpringApplication.run(RetryApplication.class, args);}@Beanpublic RetryTemplate retryTemplate() {final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();//设置最多执行次数, 包含第一次执行,下面配置成3,则第一次执行出现异常后最多会再重试2次simpleRetryPolicy.setMaxAttempts(3);final FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();//设置重试间隔时间  单位 msfixedBackOffPolicy.setBackOffPeriod(1000L);return RetryTemplate.builder().customPolicy(simpleRetryPolicy).customBackoff(fixedBackOffPolicy).build();}
}

4.2.添加任务重试失败之后的降级处理回调函数

@Slf4j
@Component
public class CustomRecoveryCallback implements RecoveryCallback<String> {@Overridepublic String recover(RetryContext retryContext) {log.error("fallback,retryCount:{},error msg:{}",retryContext.getRetryCount(),retryContext.getLastThrowable().getMessage());return "fallback";}
}

4.3.通过retryTemplate.execute执行需要重试的任务

@Slf4j
@Service
public class RetryServer  {@Autowiredprivate RetryTemplate retryTemplate;@Autowiredprivate CustomRecoveryCallback customRecoveryCallback;public void retryTemplateTest() {//第一个参数是只需要执行的方法,第二个参数是降级处理方法retryTemplate.execute(f->function(),customRecoveryCallback);}/*** 具体的执行任务*/public String function(){log.info("retryTemplateTest,当前时间:{}",LocalDateTime.now());throw new RuntimeException("test retry error");}}

4.4.使用junit进行测试

@SpringBootTest
class RetryApplicationTests {@Autowiredprivate RetryServer retryServer;@Testvoid contextLoads() {retryServer.retryTemplateTest();}}

可以看到测试得到的结果和注解的方式是一样的,都只执行了三次任务。
在这里插入图片描述

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

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

相关文章

哪些洗地机比较好?洗地机选购指南

随着社会生活水平的提高&#xff0c;人们对居家环境的卫生和清洁要求不断提升。家用洗地机作为一种先进的清洁工具&#xff0c;带来了许多便利和优势&#xff0c;特别是在解决一些特殊需求的家庭环境方面。 以下是一些家用洗地机的优势和适用场景&#xff1a; 1.高效清洁&…

Hive用户自定义函数之UDF开发

在进行大数据分析或者开发的时候&#xff0c;难免用到Hive进行数据查询分析&#xff0c;Hive内置很多函数&#xff0c;但是会有一部分需求需要自己开发&#xff0c;这个时候就需要自定义函数了&#xff0c;Hive的自定义函数开发非常方便&#xff0c;今天首先讲一下UDF的入门开发…

爬虫如何获取免费代理IP(二)

89ip代理爬取代码实现 一、代码实现 import requests import time import random from fake_useragent import UserAgent from lxml import etree import os import csv""" 89ip代理爬取 """class IPSipder(object):def __init__(self):self.u…

macbook电脑2024免费好用的系统清理优化软件CleanMyMac X4.14.7

CleanMyMac X2024来帮助你找到和删除不需要的文件。CleanMyMac X是一款专业的mac清理软件&#xff0c;它可以智能地扫描你的磁盘空间&#xff0c;找出并删除大型和旧文件&#xff0c;系统垃圾&#xff0c;iTunes垃圾&#xff0c;邮件附件&#xff0c;照片库垃圾等&#xff0c;让…

那些高级工程师才知道的只有几行代码却功能强大python自动化脚本,号称掌握这个python库让你工作效率变得比别人遥遥领先

那些高级工程师才知道的只有几行代码却功能强大python自动化脚本,号称掌握这个python库让你工作效率变得比别人遥遥领先。 如果你也厌倦了每天重复同样乏味的工作?Python,凭借它的简单和通用性,能够为你的问题提供最佳方案。 在本文中,我们将探索10个Python脚本,这些脚本…

数据结构学习 Jz48最长不含重复字符的子字符串

关键词&#xff1a;哈希表 动态规划 滑动窗口 用时&#xff1a;40min 哈希表 动态规划 题解&#xff1a;我觉得这个写的很好。 题目&#xff1a; 方法一&#xff1a; 哈希表 滑动窗口 思路&#xff1a; 我一开始没想到用一个左指针做滑动窗口。 哈希表&#xff1a;存之前…

七:Day06_redis高级01

第一章 Redis入门 1.1 节 什么是NoSql型数据库 NoSQL ,泛指非关系型的数据库, NoSQL Not Only SQL,它可以作为关系型数据库的良好补充。NoSQL 不依赖业务逻辑方式存储&#xff0c;而以简单的key-value模式存储。因此大大的增加了数据库的扩展能力。 SQLNoSQL数据结构结构化非…

P59 生成式对抗网络GAN-理论介绍 Theory behind GAN

Object Normal Distribution 的数据 经过 Generator 后生成分布更加复杂的PG. 真实数据的分布为 Pdata , 希望 PG和Pdata 越近越好 LOSS 是 两者之间的分布距离 问题: 如何计算 divergence? Sampling is goog enough Discriminator 希望V越大越好 y~Pdata 代表从 Pdata里…

zabbix离线安装 zabbix api批量添加主机

持续更新最新版本… 全自动安装方法 下载一键安装脚本 一键安装脚本执行命令全自动安装 tar -zxvf zabbix-rocky_8_zabbix_6.0.x_mysql.tar.gz cd zabbix-rocky_8_zabbix_6.0.x_mysql sh autosetup.sh installRocky8.9系统下载Rocky系统bug报告 手动安装方法 操作系统&…

Java 语言概述

Java 概述 是 SUN&#xff08;Stanford University Network&#xff0c;斯坦福大学网络公司&#xff09;1995年推出的一门高级编程语言 是一种面向 Internet 的编程语言。Java 一开始富有吸引力是因为 Java 程序可以在 Web 浏览器中运行。这些 Java 程序被称为 Java 小程序&am…

知识付费平台搭建?找明理信息科技,专业且高效

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…

Stable Diffusion模型概述

Stable Diffusion 1. Stable Diffusion能做什么&#xff1f;2. 扩散模型2.1 正向扩散2.2 反向扩散 3. 训练如何进行3.1 反向扩散3.2 Stable Diffusion模型3.3 潜在扩散模型3.4 变分自动编码器3.5 图像分辨率3.6 图像放大 4. 为什么潜在空间是可能的&#xff1f;4.1 在潜在空间中…