延迟业务
这是个很常见的业务场景,比如说凌晨开奖活动,用户订单20分钟没有支付会过期等等
实现方案
定时器
比如说我们凌晨开奖的业务是使用定时器去执行的,就是定时器扫描去执行
缺点:
会有所延迟,比如定时器5分钟扫一次,所以对于开奖来说是有延迟的。
MQ方案
-
比如说RocketMQ方案,但是这个只能延迟一定的时间间隔,预设值的延迟时间间隔为:1s、 5s、 10s、 30s、 1m、 2m、 3m、 4m、 5m、 6m、 7m、 8m、 9m、 10m、 20m、 30m、 1h、 2h
Q:如果我要自定义延迟时间呢?
-
滴滴开源分布式消息中间件DDMQ
先看夏延迟队列的实现,以及介绍:
上面这张图描述了 Chronos 的总体结构;简单来说,生产 SDK 通过 PProxy 提供的 sendDelay RPC 将延时消息发送到 PProxy, 然后由 PProxy 将消息生产到 Chronos 固定的内部 topic 上(chronos_inner_xxx)。Chronos 模块再去消费 inner topic 的消息并将消息存储到本地的 RocksDB 里去。基于本地内置的 RocksDB 存储引擎构造一个时间轮服务,会将到期的消息再发送给 PProxy,以供业务方消费或 HTTP 推送给业务方。
个人理解:就是发送延迟消息的时候是使用异步去把消息塞到一个pproxy储存里面,然后Chronos 消费之后,存到本地本地RocksDB里头,类似数据库,Chronos 有个时间轮去定时捞即将过期的数据,然后发送mq进行实时消费。
优点
- 时间可以自定义,过期时间存储到消息里头
- 时间轮使用起来也不会太重,可以很快的查询数据,批量捞数据
redis
思路:zset去保存延迟信息,然后也是一个时间轮去扫,执行完就删除。
缺点:
- 数据量大的时候redis不好整