千万级Push链路演进之路
背景:该业务场景常见于促销活动通知,有时候运营配置某些活动后,要全量的通知给用户。在该项目中,push通知链路共有三个阶段,伴随用户量和业务复杂度的上升,不断地对该链路进行优化。
阶段一:初期,滚动拉取用户数据,采用线程池或for循环,调用推送接口。进行模板组装和SDK调用

瓶颈:
- 性能效率方面:
- 资源占用高:若用
for循环调用推送接口,需依次处理每个用户,用户量大时耗时久,易引发系统长时间资源占用,拖慢其他业务。 - 吞吐量受限:线程池若线程数设置不合理,或无有效任务队列、拒绝策略,高并发下会线程竞争、任务积压,降低推送吞吐量,无法及时触达大量用户。
- 资源占用高:若用
- 稳定性与可靠性方面:
- 异常影响范围大:滚动拉取用户和循环推送中,单个用户处理出错,若未妥善隔离,可能让整个循环中断或影响其他用户处理,降低推送成功率与系统稳定性。
- 缺乏容灾重试:未对失败推送任务有效重试、降级,遇到网络抖动等临时问题,会大量丢失推送,影响活动触达效果,且难定位恢复故障。
- 业务灵活性与扩展性方面:
- 耦合度高:模板组装、SDK 调用和用户拉取推送流程耦合,后续要换推送 SDK 或改模板,需改动大量代码,增加维护成本与升级风险。
- 难适配复杂场景:业务复杂后,如按用户分层、分时段推送,现有简单循环难扩展,要大改流程才能支持,限制业务创新优化。
阶段二:引入mq和模块划分

成效:
但这种升级后仍存在瓶颈:
最终版本:以40w用户举例,实际可以支持千万级用户pus

优势:
- 效率与资源优化:
- 任务拆分与 Batch 处理:通过 “活动消费者拆分用户 ID 区间任务(1000 个用户为 1 个任务,再拆 100 个为 1 个 list )” + “线程池 + MQ 的 batch 消息”,大幅减少网络请求次数。比如 1k 数据,原单条推送需 10s,Batch 处理仅需 100ms ,提升推送效率。
- 多节点并行:用户提取消费者多个节点并行,结合节点多线程(如 4C8G 机器 30 线程),将推送耗时从阶段二的高耗时,优化到分钟级,极大提升并发处理能力与时效性。
- 幂等性保障:引入 Redis 判断是否发送过,推送成功更新 Redis ,避免同一用户重复推送,解决阶段二可能的重复推送问题,保证推送幂等性,减少无效处理,提升系统可靠性与用户体验。
- 任务流程精细化:细化推送流程各环节(从活动创建发 MQ ,到活动消费者拆分任务、用户提取消费者分批处理,再到推送服务消费者线程池处理),通过 “获取最大用户 ID → 拆分区间 → Batch 处理 → 多节点并行”,让大规模用户推送任务分配更合理,充分利用资源,适配高并发场景。
最后,此版本以可满足当时项目的用户体量和时效要求
本文来自博客园,作者:难得,转载请注明原文链接:https://www.cnblogs.com/zhangbLearn/p/18996683

浙公网安备 33010602011771号