Node.js实现基于Redis的延迟队列

本文介绍了如何使用Node.js和Redis实现一个延迟队列,包括接口设计、遇到的问题及解决方案,如数据结构选择、任务转换和消费。文章强调了核心逻辑、优化点和总结,适合想要了解延迟队列实现的读者。
摘要由CSDN通过智能技术生成

Node.js实现基于Redis的延迟队列

写代码的过程中,偶尔会因为业务需求而用到延迟队列,经典场景如:订单的超时关闭,签到提醒等,之前一般选择现成的云服务,但这次本着学习的目的就尝试自己实现了一番。实现的指导思想来自有赞延迟队列设计这篇文章,对于延迟队列使用场景、作用不太清楚的朋友可以通过这篇文章补一补。

核心流程与设计理念照有赞的文章来,自己这篇文章主要讲实现的方式与过程中遇到的问题,所以在看本文之前建议先阅读一遍有赞原文。

代码依赖所在的业务框架环境所以无法独立运行,但核心逻辑都包含在内,请与文字结合理解。

接口

由于自己的目的不是独立运行一个延迟队列的服务,所以接口方面就没有做成标准的:添加、获取、完成、删除,而是与业务绑定,具体下来主要就两个接口:

  • pushTask(id, topic, delay, ttr, body)

往topic中push一个task,延迟delay秒后执行,ttr指的是task从ready中被取走而没有被确认消费成功,间隔多久又会变成ready,body是业务决定的消息内容

// 之所以不用job,是因为task在视觉上比job好看

  • onTopic(topic, fn, frequency)

等待task就绪,当某topic中有就绪的task时,会调用fn,fn返回一个Promise,成功则会从队列中移除task并保存到mysql,frequency是onTopic获取就绪task消费完成后取下一个的间隔时间

这两个接口分别对应生产者和消费者使用,拿关闭订单举例,负责关闭订单的模块调用onTopic,而其他产生订单的地方则调用pushTask即可。

遇到的问题

自己读了两遍有赞的那篇文章后没开始写之前,觉得理论设计已经到位,那实现应该会比较简单,但在真正撸代码的过程中,还是冒出一些问题,挑重要的与大家分享:

Redis数据结构选择

能实现这个延迟队列,基本全靠Redis,那不同数据应该决定使用何种数据结构?

我们用定时器扫描delay task,发现task到期了,就将其移动到ready中,在这一步针对delay task的数据结构选择,需要着重考虑扫描的效率,如以下两个方案:

A方案:使用Hash,taskId => timestamp,每次在代码内扫描整个Hash列表࿰

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值