关于消息推送方案的讨论

2023-07-04 14:32:30 +08:00
 ben548
背景:运营可以配置无上限的活动,在活动列表和详情中,用户可以进行关注,关注后需要在活动开始前 15 分钟向推送活动开始的通知消息。
当前方案:创建完活动之后向延迟队列中投递一个执行时间为(活动开始时间-15 分钟)的任务,目前关注用户存储在 redis 的 zset 中,向延迟队列中投递的是活动的 id 信息,延迟队列消费到这条消息的时候,从关注的用户 zset 中拉取用户 id 进行消息推送。
延迟队列的设计:目前是依赖 redis ,生产者向 redis 的 zset 中投递 task 信息,score 是活动的通知时间(活动开始时间-15 分钟),然后轮询这个 task 的 redis key ,读取到期是任务信息,读取到之后将该任务信息投递到 redis 的 list (通过 rpush )中,消费者则一直读取这个 list 队列(通过 lpop )。
目前想探讨的是:这个方案是否在活动很多的时候导致推送消息的延迟(虽然可以通过增加消费者来缓解,正常哪怕是一个活动有百万级别的活动关注者(极其罕见),从 redis 的 zset 中分页拉取出来并投递消息,一般处理时长不会超过 10 分钟)
但是隐隐约约还是觉得是不是还有更好的方案呢?可以尽量减少延迟的方案。
2399 次点击
所在节点    Redis
13 条回复
mineralsalt
2023-07-04 14:40:27 +08:00
轮询 redis 真的是太不优雅了, 不如扔一个 RocketMQ 延时消息, 消费者线程弄多些, 消费起来会很快
ben548
2023-07-04 14:42:23 +08:00
@mineralsalt 确实,但是公司目前只有 kafka 这一个 mq ,如果有类似 rabbitmq 那样的组件,那处理起来就很容易很简单了(当然也是依赖加消费者。。。)
npe
2023-07-04 15:12:51 +08:00
Redis 的队列谨慎使用,ack 不好搞。用 Kafka 、RocketMQ ,多搞几个 consumer 即可。另外消息推送,可以降低下消息 priority 。
beryl
2023-07-04 15:20:27 +08:00
正常用 1#的 rocketMQ 延时消息基本可以满足。
没做过类似的业务,不过想到另一个方案,是不是可以提前推送到客户端,假设业务是可以至少提前半小时配置号消息的,然后客户端去校验本地的消息队列中的数据。

需要考虑:消息临时撤销、内容变更如何解决(客户端推送之前查询?如果一千万客户端,一分钟之内本地推送完成,推送之前查询下消息是否生效以及消息内容,服务端接口 QPS:16 万,对于一千万客户端的程序来说应该可以接受
wxw752
2023-07-04 15:29:28 +08:00
我是用 rabbitmq 延迟消息插件解决的。消费者监听死信队列,开线程池处理消息
wqhui
2023-07-04 15:43:38 +08:00
如果不是必须实时投递的话,把消息带上生效时间提前扔下去,用户端筛选出到时间的来提示
rabbitmq 的延时队列其实也有个问题,同一条队列消息到期时间必须是递增的,即队列头消息必须先于队列其他消息过期才能正常使用,否则会阻塞,这种情况下只能保证不早设置的时刻取到消息。对于过期时长不是固定的,最好是分队列
LeegoYih
2023-07-04 15:46:14 +08:00
基于延时队列是最常见的做法。

问问产品接不接受本地消息推送,比如活动是 10:15 ,用户点击关注的时往本地设置一个 10:00 的定时任务。很多手游体力提醒都是这种方式的。
sipt
2023-07-04 16:01:56 +08:00
Redis Keyspace Notifications 也许能给点灵感
vitoliu
2023-07-05 00:12:35 +08:00
你的设计好在简单,能够快速迭代,代码也直观。小活动、用户量少推送起来不费力。
大流量不建议。
N 个用户关注了 M 个活动,你的存储底线需要存 N x M 个数据。重试和断点续推的能力为 0 。
一般订阅活动后,客户端会起任务定时拉任务状态即可。
如果是服务端统一做这事儿一条条推,还是推荐 MQ 可靠性会高一些。
nealHuang
2023-07-05 09:18:57 +08:00
可以嫖 zookeeper 的 过期桶队列源码过来?
starxg
2023-07-05 12:41:47 +08:00
ben548
2023-07-05 17:43:06 +08:00
@starxg 哈哈,go-zero 的延迟队列貌似用了这个组件
ben548
2023-07-05 17:43:34 +08:00
@nealHuang 大佬的方案有点高端啊。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/953983

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX