每日一博 - 使用环形队列实现高效的延时消息

简介: 每日一博 - 使用环形队列实现高效的延时消息

d0fdb2e70e1847b2b9749789048967d3.png

Pre


来个场景: 24小时后将未进行某个Action的业务,执行另外一个动作。 比如 24小时未付款的订单,取消。

你可能会说

89395785d754489f98843d72bb050093.png

方案A


来个定时呗 ,每隔半小时 ,扫描数据库订单表,将完成时间超过24小时的订单,取消掉。

cce5a163221a4561b317ea0d19b32144.png

But…

这方案有些明显的缺点啊,老哥

  • (1)轮询效率比较低
  • (2)时效性不好,假设每小时轮询一次,最坏的情况下,时间误差会达到1小时;

那如何既保证效率的同时,又保证实时性呢?

b41fed49e88f407999ee70c0ed29582e.png


方案B


来说下核心思路

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

  • 环形队列。例如可以创建一个大小为3600的环形队列
  • 任务集合。环上每一个格是一个Set

同时,启动一个timer:

  • 每隔1s,timer在环形队列中移动一格
  • 用一个Current Index来标识当前所在的格;

Task结构中包含两个重要属性:

  • Cycle-Num:用于标记当第几圈扫描到这个格时,执行任务
  • Task-Function:到时间后需要执行的任务函数

0aae981f1e3940879f3ddf977356ac31.png



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


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


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


Current Index每秒移动一格,当移动到下一格时,遍历这个格的Set,看看每个Task的Cycle-Num是不是0:

  • 如果不是0,说明任务时间还没到,还需要多移动几圈,将Cycle-Num减1;
  • 如果是0,说明到这个Task的执行时间了,取出Task-Funciton丢给工作线程执行,并把这个Task从Set<Task>中删除
Warning : 不要直接用timer线程来执行任务


总结


总体思路就是这个样子,总结下有点

  • (1)效率高,无需再轮询订单表;一个订单,任务只执行一次
  • (2)实时性好,精确到秒


相关文章
|
机器学习/深度学习 数据采集 人工智能
GAN的主要介绍
【10月更文挑战第6天】
|
10月前
|
人工智能 安全 测试技术
山石网科×阿里云通义灵码,开启研发“AI智造”新时代
山石网科与阿里云的合作由来已久,双方在云计算、网络安全等领域保持着紧密的合作关系。此次山石网科全面接入阿里云通义灵码专属版,是双方合作关系的进一步深化,也是双方共同推动AI技术在网络安全领域应用的一次重要实践。未来,山石网科将继续与阿里云携手共进,积极探索AI技术在网络安全领域的创新应用,不断提升产品研发效率和服务质量,为用户提供更智能、更安全的网络安全解决方案,共同守护数字世界的安全!
山石网科×阿里云通义灵码,开启研发“AI智造”新时代
|
存储 负载均衡 算法
Nacos注册表解读
Nacos注册表解读
|
API 开发者 Python
API接口:原理、实现及应用
本文详细介绍了API接口在现代软件开发中的重要性及其工作原理。API接口作为应用程序间通信的桥梁,通过预定义的方法和协议实现数据和服务的共享。文章首先解释了API接口的概念,接着通过Python Flask框架示例展示了API的设计与实现过程,并强调了安全性的重要性。最后,本文还讨论了API接口在Web服务和移动应用程序等领域的广泛应用场景。
|
SQL 缓存 PHP
【PHP开发专栏】PHP数据库查询优化技巧
【4月更文挑战第29天】本文探讨了PHP数据库查询优化技巧,包括数据库设计的规范化与反规范化,合理使用索引,优化查询逻辑,以及避免SELECT *。在SQL查询优化中,利用EXPLAIN分析查询、优化JOIN操作和子查询,以及改进WHERE条件。PHP层面的优化涉及预处理语句、缓存查询结果、分页查询优化和异步处理。此外,还提到了高级技术如数据库分区、读写分离和分布式数据库。通过这些方法,开发者能提升查询效率,优化应用性能和用户体验。
277 1
|
机器学习/深度学习 数据可视化 TensorFlow
深入探索TensorBoard:使用可视化工具提升模型调试与优化的效率和效果
【8月更文挑战第31天】在深度学习领域,理解和优化复杂的神经网络模型充满挑战。TensorBoard作为TensorFlow的强大可视化工具,能帮助我们清晰地展示模型结构、激活值、损失函数变化等关键信息,从而更高效地调试和优化模型。
497 0
|
机器学习/深度学习 Java Python
代码解密 | 2024春晚刘谦魔术与约瑟夫环问题
2024春节联欢晚会中,刘谦老师的魔术节目可以说是我心目中的全场最佳~春晚刚结束网上就有大佬给出了第二个魔术(拼扑克牌)的数学模拟,也有大佬发布了代码程序。博主在模拟了魔术过程之后,也在此分享一下程序代码和思路。同时,也借此回顾一下经典的数学问题:约瑟夫环问题。
358 8
|
人工智能 开发者
Kimi Chat:国内AI新星,20万字超长文本处理的突破者
【2月更文挑战第12天】Kimi Chat:国内AI新星,20万字超长文本处理的突破者
3321 2
Kimi Chat:国内AI新星,20万字超长文本处理的突破者
|
存储 SQL 关系型数据库
Pandas与数据库交互:实现高效数据交换与存储
【4月更文挑战第16天】本文介绍了Pandas与数据库交互的方法,包括使用`read_sql`和`to_sql`函数连接SQLite、MySQL等数据库。为了提升数据交换效率,建议采用批量操作、优化SQL查询和使用事务。在数据存储优化方面,选择合适的数据类型、压缩数据以及使用分区或分片都是有效策略。通过这些方法,可实现Pandas与数据库间高效、可靠的数据处理和分析。
|
消息中间件 SQL Rust
为什么选择 Kotlin 重写后端服务?
为什么选择 Kotlin 重写后端服务?
1064 0
为什么选择 Kotlin 重写后端服务?

热门文章

最新文章