延迟队列

把 Server饭 当作一个可靠的延迟队列。

为什么需要延迟队列

很多业务场景都要用到延迟队列:

  • 新订单如果未付款在一个小时后自动关闭。
  • 订单发货后15天自动确认收货。
  • 餐厅消费后一个小时请求评价。

类似的还有很多,不一一列举了。

延迟队列的误解

因为叫队列,所以如果项目用了某种队列,第一反应就是去看这种队列是不是支持延迟队列

很不幸,各家队列和云服务商提供的队列,都对延迟队列支持的不怎么好。只有 RabbitMQ 稍微好一点。

为什么会这样呢?因为延迟队列和传统的队列压根是两种东西。想兼容当然不容易了。 传统的队列一般都是先进先出,可以是生产消费模式或者广播订阅模式。更侧重于性能、可靠性、顺序性等方面的改善。

但是延迟队列实际上是一种持久存储的计划任务,它更应该和传统的队列结合使用。Job存储在一个安全可靠的地方,到时间了拿出来放某个队列供消费。

为什么 Server饭 是一个不错的选择

  1. 网上有很多在代码中实现延迟队列的教程,各个语言也有轮子,这个方式是最不推荐的。把信息存在内存当中,难道服务永远不升级重启了?
  2. 用 Redis 当延迟队列,可以使用 zset 或者 过期事件实现。问题是同样的,一般的 redis 没那么可靠,除非你用的有可靠性保障的 Redis 集群。
  3. 自己写一个有独立存储的延迟队列。如果你有这个力气当然是可以的……一般来说延迟队列在总的需求中占比很小,你可能没有那么多的时间预算去写一个服务,然后维护它。
  4. 想找一个类似的云服务,结果这个功能太小了,找不到。

这个时候我们开箱即用的接口就很方便了。

一个例子

我已经在 坚橙艺术 中实际使用了一段时间,分享给大家。

  1. 订单123卖家发货后,调用 延迟任务接口发送15天订单完成 123
  2. 如果买家在收货之后手动点击了确认收货,则系统自动调用订单完成的函数。
  3. 如果卖家在发货一周后着急确认,客服在询问买家确实收货后,在 LetServerRun 公众号发送 订单完成 123
  4. 15天后,Agent 收到当时设定的延迟任务,会再执行一次。这就要求这个订单完成需要判断订单状态,保证自己是幂等的,重复执行也不会出错。
最后修改 2021年5月6日: rename to server.fan (2159d77)