1分钟实现“延迟消息”功能

软件工程:数据字典 数据字典 阅读详情

一、缘起

很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。

例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。

一般来说怎么实现这类“48小时后自动评价为5星”需求呢?

常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。

假设订单表的结构为:t_order(oid, finish_time, stars, status, …),更具体的,定时任务每隔一个小时会这么做一次:

select oid from t_order where finish_time > 48hours and status=0;

update t_order set stars=5 and status=1 where oid in[…];

如果数据量很大,需要分页查询,分页update,这将会是一个for循环。

方案的不足:

(1)轮询效率比较低

(2)每次扫库,已经被执行过记录,仍然会被扫描(只是不会出现在结果集中),有重复计算的嫌疑

(3)时效性不够好,如果每小时轮询一次,最差的情况下,时间误差会达到1小时

(4)如果通过增加cron轮询频率来减少(3)中的时间误差,(1)中轮询低效和(2)中重复计算的问题会进一步凸显

如何利用“延时消息”,对于每个任务只触发一次,保证效率的同时保证实时性,是今天要讨论的问题。

 

二、高效延时消息设计与实现

高效延时消息,包含两个重要的数据结构:

(1)环形队列,例如可以创建一个包含3600个slot的环形队列(本质是个数组)

(2)任务集合,环上每一个slot是一个Set<Task>

同时,启动一个timer,这个timer每隔1s,在上述环形队列中移动一格,有一个Current Index指针来标识正在检测的slot。

Task结构中有两个很重要的属性:

(1)Cycle-Num:当Current Index第几圈扫描到这个Slot时,执行任务

(2)Task-Function:需要执行的任务指针

 

 

假设当前Current Index指向第一格,当有延时消息到达之后,例如希望3610秒之后,触发一个延时消息任务,只需:

(1)计算这个Task应该放在哪一个slot,现在指向1,3610秒之后,应该是第11格,所以这个Task应该放在第11个slot的Set<Task>中

(2)计算这个Task的Cycle-Num,由于环形队列是3600格(每秒移动一格,正好1小时),这个任务是3610秒后执行,所以应该绕3610/3600=1圈之后再执行,于是Cycle-Num=1

Current Index不停的移动,每秒移动到一个新slot,这个slot中对应的Set<Task>,每个Task看Cycle-Num是不是0:

(1)如果不是0,说明还需要多移动几圈,将Cycle-Num减1

(2)如果是0,说明马上要执行这个Task了,取出Task-Funciton执行(可以用单独的线程来执行Task),并把这个Task从Set<Task>中删除

使用了“延时消息”方案之后,“订单48小时后关闭评价”的需求,只需将在订单关闭时,触发一个48小时之后的延时消息即可:

(1)无需再轮询全部订单,效率高

(2)一个订单,任务只执行一次

(3)时效性好,精确到秒(控制timer移动频率可以控制精度)

三、总结

环形队列是一个实现“延时消息”的好方法,开源的MQ好像都不支持延迟消息,不妨自己实现一个简易的“延时消息队列”,能解决很多业务问题,并减少很多低效扫库的cron任务。

一、Abaqus CAE 入门操作(薄膜应力计算) 阅读详情

相关推荐

uniapp 使用摄像头 live-pusher (APP)

uniapp 中开发 app 时使用live-pusher踩过的坑

随身笔记 1万+

实现延时消息的6种方案

延时消息(定时消息)指的在分布式异步消息场景下,生产端发送一条消息,希望在指定延时或者指定时间点被消费端消费到,而不是立刻被消费。 延时消息适用的业务场景非常的广泛,在分布式系统环境下,延时消息的功能一般会在下沉到中间件层,通常是 MQ 中内置这个功能或者内聚成一个公共基础服务。 本文旨在探讨常见延时消息的实现方案以及方案设计的优缺点。 实现方案 基于外部存储实现的方案 这里讨论的外部存储指的是在 MQ 本身自带的存储以外又引入的其他的存储系统。 基于外部存储的方案本质上都是一个套路,将 M

Java搜索工程技术栈 2698

QT+SOEM主站协议库实战指南—从编译到嵌入式应用

本文提供了一份QT与SOEM开源EtherCAT主站协议库的集成实战指南。详细介绍了在Windows和Linux平台下编译SOEM库的步骤,并讲解了如何将其无缝集成到QT项目中,构建具备实时监控与控制功能的工业上位机应用。内容涵盖从环境搭建、核心协议开发到嵌入式部署与优化的全流程,为开发高性价比、自主可控的工业控制解决方案提供完整路径。

u6v7w8x的博客 437

一口气说出 6 种实现延时消息的方案,还有谁不会?!

延时时间最短的会放在头上,时间越长越靠后。第二层在内存中,当消息的投递时间即将到来的时候,会将这个小时的消息索引(索引包括消息在schedule log中的offset和size)从磁盘文件加载到内存中的hash wheel上,内存中的hash wheel则是以500ms为一个刻度。获取中最近的延时消息,然后wait(执行时间-当前时间),这样就不需要浪费资源到达时间时会自动响应,如果有新的消息进入,并且比我们等待的消息还要小,那么直接notify唤醒,重新获取这个更小的消息,然后又wait,如此循环。

m0_71777195的博客 492

BIDS数据存储格式介绍与dcm2bids安装与使用

BIDS格式&dcm2bids安装与使用

machinelearning_er的博客 7308

5大步骤!轻松玩转Dorisoy.Rigger:基于.NET Core 6、MAUI和Blazor的多数据库开发框架生成器

各位小伙伴,你们是否厌倦了每次项目启动都要从头配置数据库连接、编写重复的代码?今天,我们就来聊聊如何使用Dorisoy.Rigger这个强大的开发框架生成器,让你的.NET Core 6、MAUI和Blazor项目开发变得简单又高效!准备好迎接开发的新乐趣了吗?让我们一起开始吧!接下来,我们需要定义数据模型。假设我们有一个简单的用户表,包含ID、用户名和密码字段。在项目中创建一个新的类文件,命名为User.csset;set;set;这段代码定义了一个用户模型,其中包含了用户的ID、用户名和密码。

java专栏 1738

如何实现延迟消息

分析延迟消息在业界成熟开源中间件的实现,总结提炼其设计难点和主流设计思想。

qq_40483675的博客 1728

AgentScope Java 2.0 项目实战:从零构建企业级自主Coding Agent

本文基于 AgentScope Java 框架,完整拆解两个生产级 AI Agent 项目的从零开发全过程。其一是企业级自主编码机器人(agentscope-codingagent),支持 Issue→PR 自动实现、PR Code Review、Docker 沙箱隔离执行与多通道接入;其二是个人 AI 助手管理平台(agentscope-paw),采用 Spring Boot + React 全栈架构,支持多 Agent、技能市场与多 IM 通道。

program哲学 833

Java延时消息的实现

Java延时消息的实现

果酱 の 博客 6380

YOLO11创新改进系列:卷积,主干 注意力,C3k2融合,检测头等创新机制(已更新110+)

本专栏提供详细的 YOLO11 教程,包括基础知识、源码解析、入门实践、算法改进和项目实战,适合发表YOLO11 学习者订阅。内容包含 100+多篇独家改进机制,适合发表论文,评分高达 96 分。订阅者将获得一键运行的改进文件及答疑交流群支持。 使用服务器的同学还可以私聊获取搭建好的运行环境。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 1万+

Python 爬虫实战:华尔街见闻精选文章爬取(反反爬 + 投资情绪分析)

Python 爬虫实战:华尔街见闻精选文章爬取(反反爬 + 投资情绪分析)

yansideyucsdn的博客 969

RabbitMQ实现延时消息的两种方法

因此我们只需要在声明正常的业务队列时添加一个可选的"x-dead-letter-exchange"参数,值为死信交换机,死信就会被rabbitmq重新publish到配置的这个交换机上,我们接着监听这个交换机就可以了。如果当一个队列各个消息的过期时间不一致时,使用死信队列就可能达不到延时的作用。当我往死信队列中发送两条不同过期时间的消息时,如果先发送的消息A的过期时间大于后发送的消息B的过期时间时,由于消息的顺序消费,消息B过期后并不会立即重新publish到死信交换机,而是会等到消息A过期后一起被消费。

柳落青 5059

Ubuntu Rtx3090 Cuda11.7 安装 pytorch3d

pytorch ubuntu pytorch3d 安装

G果的博客 2270

golang:1分钟实现“延迟消息”功能

一、缘起 很多时候,业务有"在一段时间之后,完成一个工作任务"的需求 例如:滴滴打车订单完成之后,如果用户一直不评价,48小时会将自动评价为5星 一般来说怎么实现这类48小时之后自动评价为5星的需求呢? 常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。 假设订单表的结构为:t_order(oid, finish_time, st...

OceanStar的博客 2736

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

1分钟实现“延迟消息”功能(58沈剑)

一、缘起 很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。   例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。 一般来说怎么实现这类“48小时后自动评价为5星”需求呢?   常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。 假设订单表

1994

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

1分钟实现“延迟消息”功能 ----自己理解为订单失效之类的功能

1分钟实现“延迟消息”功能原创 2017-03-15 58沈剑 架构师之路一、缘起很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。 例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。一般来说怎么实现这类“48小时后自动评价为5星”需求呢? 常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价。假设...

hyg0406的专栏 653

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

1分钟实现“延迟消息”功能 和 10w定时任务, 如何高效触发超时

  架构师之路 https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&amp;mid=2651959961&amp;idx=1&amp;sn=afec02c8dc6db9445ce40821b5336736&amp;chksm=bd2d07458a5a8e5314560620c240b1c4cf3bbf801fc0ab524bd5e8aa8b8ef0...

我是guyue,guyue就是我O(∩_∩)O 2099

MQ消息架构设计四(1分钟实现“延迟消息”功能)

转载自:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959961&idx=1&sn=afec02c8dc6db9445ce40821b5336736&chksm=bd2d07458a5a8e5314560620c240b1c4cf3bbf801fc0ab524bd5e8aa8b8ef036cf755d7eb0f6&scene=

zenghaolin510824的博客 624

高效实现延迟消息功能

高效实现延迟消息功能 高效延时消息,包含两个重要的数据结构: (1)环形队列,例如可以创建一个包含3600个slot的环形队列(本质是个数组) (2)任务集合,环上每一个slot是一个Set   同时,启动一个timer,这个timer每隔1s,在上述环形队列中移动一格,有一个Current Index指针来标识正在检测的slot。

chenglinhust的专栏 2898
上一篇: RabbitMQ和Kafka比较选择
下一篇: Spring 钩子之BeanFactoryPostProcessor和BeanPostProcessor的源码学习
shadow_zed
博客等级 码龄10年 6289粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值