webflux延迟队列逻辑更改过程记录
title : webflux延迟队列逻辑更改过程记录
author : simonLee
date : 2022/11/22 10:26
webflux延迟队列逻辑更改过程记录
一、问题背景
一个业务使用了webflux.delayElement(Duration delay)来发送延迟消息,由于是异步,发送出去无法通过别的途径拿到该延迟消息(webflux没有相关api),但新需求功能上需要对发出去的延迟消息提供终止功能,且规定时间内可重复无限次
老功能简单来说就是有一个数字,数字在选择时间内按照正态分布有规律的一定时间间隔发送延迟消息,并对消息进行后续处理。例:设定数字10000,在半小时内,按一定时间间隔平分10000发送延迟消息。
新功能就是在老功能的基础上,支持中途中断往后的所有消息。
二、当前实现代码

可以见到,在delayElement后使用了doOnNext()做后续操作以及flatMap重新封装流对象,而想要做中途终止,必须能拿到延迟队列。"理解是第一步",我们需要先了解这几行代码的底层逻辑,才能对其进行修改。
三、逻辑详解
3.1创建事件链
方法开头使用了一个Mono对象作为事件链的头,由于webflux都是使用流式编程,使用一个对象便可把所有遍历对象连接起来。
3.2delayElement
先附上delayElement源码

该入参是一个Duration类,意为多久之后消费。在内部又调用了一个重载方法,入参为Duration和Scheduler,时间以及reactor的调度器。
Schedulers.parallel()是调度器的一个线程模型。
从这里我们大概可以知道webflux封装的delayElement也是通过线程延时执行的
3.3publishOn
下一步的publishOn则是将链中的调度器调整为boundedElastic,是一个有界可复用线程池,可动态调节。该线程池可适当解决"且规定时间内可重复无限次"产生的内存问题。
该线程池容量是CPU核心数的10倍,最多提交10万条任务。如果是延时调度,那么延时开始时间是在有线程可用时才开始计算。
3.4doOnNext
再下一步的doOnNext是在不对序列造成改变的情况下,发出元素,相当于做一些额外的逻辑。
在这里doOnNext里是做调用腾讯云操作
3.5flapMap
最后一步是flapMap,即重新执行逻辑修改元素内容。这里还做了落库操作并返回落库方法返回的元素。
四、代码总结
// 由调用链可知道
/*
代码相当于做了这样的操作,封装流,交由webflux执行
*/
eventChain.
.delayElement()
.publishOn()
.doOnNext()
.flatMap()
.delayElement()
.publishOn()
.doOnNext()
.flatMap()
.delayElement()
.publishOn()
.doOnNext()
.flatMap()
...重复
从Mono模型上来看,当链路中有一个元素终止或者抛错那么整条链路就会中断

五、逻辑修改总结
由于该方法是封装整个链路给到webflux,所以我们只需在封装前给定一个批次号用作是否终止判断,在发送延迟消息后加上一个终止条件判断(暂定redisKey)的元素,若是已终止则在此元素抛出流异常,则整个流会捕获异常结束被gc掉,内存也得以保障。
webflux延迟队列逻辑更改过程记录的更多相关文章
- RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本
RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...
- 基于Redis实现延迟队列
背景 在后端服务中,经常有这样一种场景,写数据库操作在异步队列中执行,且这个异步队列是多进程运行的,这时如果对同一资源进行写库操作,很有可能产生数据被覆盖等问题,于是就需要业务层在更新数据库之前进行加 ...
- RabbitMQ 延迟队列,消息延迟推送
目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...
- Dyno-queues 分布式延迟队列 之 基本功能
Dyno-queues 分布式延迟队列 之 基本功能 目录 Dyno-queues 分布式延迟队列 之 基本功能 0x00 摘要 0x01 Dyno-queues分布式延迟队列 1.1 设计目标 1. ...
- Dyno-queues 分布式延迟队列 之 辅助功能
Dyno-queues 分布式延迟队列 之 辅助功能 目录 Dyno-queues 分布式延迟队列 之 辅助功能 0x00 摘要 0x01 前文回顾 0x2 Ack机制 2.1 加入Un-ack集合 ...
- 升级Windows 10 正式版过程记录与经验
升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...
- xp硬盘安装Fedora14 过程记录及心得体会(fedora14 live版本680M 和fedora14 DVD版本3.2G的选择)
这次电脑奔溃了,奇怪的是直接ghost覆盖c盘竟然不中.之前电脑上硬盘安装的fedora14操作系统,也是双系统.不知道是不是这个问题,记得同学说过,在硬盘装fedora之后,要手动修改c盘隐藏的那个 ...
- 详细分析SQL语句逻辑执行过程和相关语法
本文目录: 1.SQL语句的逻辑处理顺序 1.2 各数据库系统的语句逻辑处理顺序 1.2.1 SQL Server和Oracle的逻辑执行顺序 1.2.2 MariaDB的逻辑执行顺序 1.2.3 M ...
- Java 延迟队列使用
延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到…… 应用场景比较多,比如延时1分钟发短 ...
- php使用redis的有序集合zset实现延迟队列
延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...
随机推荐
- kubeadm init 命令执行流程
- K8S Ingress使用|常见问题列表
官方文档地址:https://kubernetes.github.io/ingress-nginx/
- Logstash: 如何创建可维护和可重用的Logstash管道
- 使用 systemd 定时器代替 cron 作业
转载自:https://mp.weixin.qq.com/s/HpDVp1sNYve8b7OdoHdGNw 创建一个定时器 首先,创建一个运行基础东西的简单的服务,例如 free 命令.举个例子,你可 ...
- logstash中关于Jdbc输入配置选项详解
Setting Input type Required clean_run boolean No columns_charset hash No connection_retry_attempts n ...
- numpy中的一些常用的关键字用法
1.np.full() 原型:numpy.full(shape, fill_value, dtype=None, order='C') eg: 2.np.flatten():该函数返回一个折叠成一维的 ...
- spring boot项目使用mybatis-plus代码生成实例
前言 mybatis-plus官方地址 https://baomidou.com mybatis-plus是mybatis的增强,不对mybatis做任何改变,涵盖了代码生成,自定义ID生成器,快速实 ...
- C#中ref和out关键字的应用以及区别
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...
- ysoserial commonscollections6 分析
利用链如下: 其中LazyMap.get()->ChainedTransformer.transform()-InvokerTransformer.transform()与CC1链一致. /* ...
- abstract关键字的使用
1.abstract:抽象的 2.abstract可以用来修饰的结构:类.方法 3.abstract修饰类:抽象类 此类不能实例化 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全 ...