Fast-Retry:一个支持百万级多任务异步重试框架【送源码】

2024-06-05 02:28

本文主要是介绍Fast-Retry:一个支持百万级多任务异步重试框架【送源码】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

假设你的系统里有100万个用户,然后你要轮询重试的获取每个用户的身份信息, 如果你还在使用SpringRetry和GuavaRetry 之类的这种单任务的同步重试框架,那你可能到猴年马月也处理不完,即使加再多的机器和线程也是杯水车薪,而Fast-Retry正是为这种场景而生。

Fast-Retry

一个高性能的多任务重试框架,支持百万级任务的异步重试、以及支持编程式和注解声明式等多种使用方式、 也支持自定义结果重试逻辑。

What is this?

与主流的Spring-Retry、Guava-Retry等单任务同步重试框架不同,Fast-Retry是一个支持异步重试框架,支持异步任务的重试、超时等待、回调。

Spring-Retry、Guava-Retry均无法支持大批量任务的重试,即使加入线程池也无法解决,因为实际每个重试任务都是单独的同步逻辑,然后会会占用过多线程资源导致大量任务在等待处理,随着任务数的增加,系统吞吐量大大降低,性能指数级降低,而Fast-Retry在异步重试下的性能是前者的指数倍。

下图是三者的性能对比

  • 测试线程池: 8个固定线程

  • 单个任务逻辑: 轮询5次,隔2秒重试一次,总耗时10秒

  • 未测预计公式:当我们使用线程池的时候, 一般线程池中 总任务处理耗时 = 任务数/并发度 x 单个任务重试耗时

图片

图片

可以看到即使是处理100万个任务,Fast-Retry的性能也比Spring-Retry和Guava-Retry处理在50个任务时的性能还要快的多的多属实降维打击,这么快的秘密在于除了是异步,重要的是当别人在重试间隔里休息的时候,Fast-Retry还在不停忙命的工作着。

即使抛开性能不谈,SpringRetry使用繁琐,不支持根据结果的进行重试,GuavaRetry虽然支持,但是又没有提供注解声明式的使用。

快速开始

引入依赖

<dependency><groupId>io.github.burukeyou</groupId><artifactId>fast-retry-all</artifactId><version>0.2.0</version>
</dependency>

有以下三种方式去构建我们的重试任务

使用重试队列

RetryTask就是可以配置我们重试任务的一些逻辑,比如怎么重试,怎么获取重试结果,隔多久后重试,在什么情况下重试。它可以帮助我们更加自由的去构建重试任务的逻辑。但如果只是简单使用,强烈建议使用FastRetryBuilder 或者 @FastRetry注解

RetryQueue就是一个执行和调度我们重试任务的核心角色,其在使用上与线程池的API方法基本一致

ExecutorService executorService = Executors.newFixedThreadPool(8);
RetryQueue queue = new FastRetryQueue(executorService);
RetryTask<String> task = new RetryTask<String>() {int result = 0 ;// 下一次重试的间隔@Overridepublic long waitRetryTime() {return 2000;}// 执行重试,每次重试回调此方法@Overridepublic boolean retry() {return ++result < 5;}// 获取重试结果@Overridepublic String getResult() {return  result + "";}
};
CompletableFuture<String> future = queue.submit(task);
log.info("任务结束 结果:{}",future.get());

使用FastRetryBuilder

底层还是使用的RetryQueue去处理, 只是帮我们简化了构建RetryTask的逻辑

RetryResultPolicy<String> resultPolicy = result -> result.equals("444");
FastRetryer<String> retryer = FastRetryBuilder.<String>builder().attemptMaxTimes(3).waitRetryTime(3, TimeUnit.SECONDS).retryIfException(true).retryIfExceptionOfType(TimeoutException.class).exceptionRecover(true).resultPolicy(resultPolicy).build();CompletableFuture<String> future = retryer.submit(() -> {log.info("重试");//throw new Exception("test");//int i = 1/0;if (0 < 10){throw new TimeoutException("test");}return "444";
});String o = future.get();
log.info("结果{}", o);

使用@FastRetry注解

底层还是使用的RetryQueue去处理, 只是帮我们简化了构建RetryTask的逻辑,并且与Spring进行整合能对Spring的bean标记了FastRetry注解的方法进行代理, 提供了重试任务注解声明式的使用方式

  • 依赖Spring环境,所以需要在Spring配置类加上@EnableFastRetry注解启用配置,这个@FastRetry注解的使用才会生效

  • 如果将结果类型使用CompletableFuture包装,自动进行异步轮询返回,否则同步阻塞等待重试结果。(推荐)

下面定义等价于RetryQueue.execute方法

// 如果发生异常,每隔两秒重试一次@FastRetry(retryWait = @RetryWait(delay = 2))public String retryTask(){return "success";}

下面定义等价于 RetryQueue.submit方法,支持异步轮询

@FastRetry(retryWait = @RetryWait(delay = 2))
public CompletableFuture<String> retryTask(){return CompletableFuture.completedFuture("success");
}

自定义重试注解

如果不喜欢或者需要更加通用化的贴近业务的重试注解,提供一些默认的参数和处理逻辑,可以自行定义一个重试注解并标记上@FastRetry并指定factory,然后实现AnnotationRetryTaskFactory接口实现自己的构建重试任务的逻辑即可。@FastRetry默认实现就是:FastRetryAnnotationRetryTaskFactory

使用建议

无论是使用以上哪种方式去构建你的重试任务,都建议使用异步重试的方法,即返回结果是CompletableFuture的方法, 然后使用CompletableFuturewhenComplete方法去等待异步重试任务的执行结果。

其他

github项目地址

https://github.com/burukeYou/fast-retry

maven仓库地址

https://central.sonatype.com/artifact/io.github.burukeyou/fast-retry-all

 福利:

扫码回复【图书】可免费领取图书管理系统源码

图片

这篇关于Fast-Retry:一个支持百万级多任务异步重试框架【送源码】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1031808

相关文章

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南

《SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南》本文将基于开源项目springboot-easyexcel-batch进行解析与扩展,手把手教大家如何在SpringBo... 目录项目结构概览核心依赖百万级导出实战场景核心代码效果百万级导入实战场景监听器和Service(核心

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1