SystemDesign | 延迟队列方案

为什么需要延迟队列?

  • 单机延迟队列:
    • 优先队列 // 该方式, 或者 Redis Zset这种方式的问题? 轮询线程Sleep后, 插入了一个需要马上处理的任务
    • DelayQueue: @todo
    • HashedWheelTimer(时间轮算法): 环形数组共n个元素, 每个元素表示一个单位时间(例如1s), 同时每个元素是一个”桶”, 指向一个链表, 链表里保存的是该秒要执行的任务. 如果放入一个x秒后执行的新任务, x大于n, 当前运行指针指向第3个元素, 那么放入数组第几个桶里呢? index = x%n + 3, 同时链表中的每个任务都保存圈数这个字段,每次指针经过这个桶, 桶中所有任务的圈数都-1, 如果圈数=0则表示要执行;
  • 分布式延迟队列:
    • Redis : blpop/brpop
    • RabbitMQ : Dead Letter Exchange

关于 HashedWheelTimer:
根据 George Varghese 和 Tony Lauck 1996 年的论文《Hashed and Hierarchical Timing Wheels: data structures to efficiently implement a timer facility》提出了一种定时轮的方式来管理和维护大量的 timer 调度。Netty 的定时任务调度就是基于时间轮算法调度 … @ref: https://www.infoq.cn/article/netty-threading-model