本文由转转平台业务负责人王计宽分享,原题“转转push系统的演进之路”,下文有修订和重新排版。
1、引言
顾名思义,push就是就是借助厂商通道把消息发送给用户的一种方式,一般用于用户的召回和活动触达,和即时通讯IM在业务上稍有区别,但技术逻辑上是相通的,不在此处赘述。
本文将从0开始讲讲转转千万级用户量消息推送系统的架构演进和迭代过程,以及遇到的常见问题的解法,希望能带给你启发。
2、术语解释
以下是本文涉及到的一些技术术语的解释:
- 1)业务属性:运营、业务、功能类推送;
- 2)推送范围: 月活、全量、定向推送、个性化推送;
- 3)目标端:一般是安卓、ios客户端;
- 4)通道:小米、华为、魅族、apns等手机厂商的常驻连接;
- 5)token: 用于设备的唯一标识,由APP本身生成;
- 6)devicetoken:用于推送的唯一标识,一般由厂商提供;
- 7)推送量:推送消息的数量;
- 8)到达率:消息到达手机的数量/推送量;
- 9)点击率:用户点击量/推送量。
3、当前架构概览

现有的架构支持后台推送、业务推送以及个性化推荐推送。
以下是相关推送业务的特点:
- 1)后台推送:一般会有标准的格式,特点是时间短、推送量大,比如8点秒杀活动;
- 2)业务推送 :一般都是业务触发,特点是实时性强、优先级高,如订单支付消息;
- 3)个性化推送:经常会和用户画像相关,特点是策略复杂、内容多样,需要有风控管理,如猜你喜欢等推荐策略。
4、技术背景——PM想推送运营活动
步骤:
- 1)PM从大数据平台上导出一部分用户集合;
- 2)RD写程序调用push接口。
问题:
- 1)N个PM都有需求,RD..........;
- 2)8点有一个突发情况,9点来一波;
- 3)每周末都要活动,推送。
解决方案:
- 1)搭建一个后台,支持根据用户ID上传,解放开发资源;
- 2)支持按照时间推送,支持文案可配;
- 3)支持安卓、IOS分端推送。
遗留的问题:PM上传了一个浏览过手机类目用户的数据集合,数据量太大,上传超时。PS:用户量大概在1000w左右+,大约300M左右的文件。
提示:
- 1)上传的时间大约在1分钟左右, 需要联系运维设置最长的链接时间,否则nginx会主动断开;
- 2)上传由同步上传,改成进度条的方式,让上传者可以看到进度;
- 3)上传和数据处理分开(我们当时是边上传,边解析文件比较慢)。
5、希望重大节日能够即时通知到活跃用户
5.1 实时推
问题描述:重大节日,推送全量用户、月活、周活数据,每次仅是文案不同,PM都需要跑大数据系统,效率太低,当天数据不可获得,平均推送需要1个多小时。
要求:
- 1)1亿的数据能够在一小时内推送完毕;
- 2)要覆盖到某一个周期内的用户(比如一个月);
- 3)支持预览,支持暂停。
分析-数据量(以2000w月活为例):
- 1) 全量用户认定为近3个月(90天)内访问过转转的用户;
- 2) 预估所有设备数量在5000w左右;
- 3) 预计占用的空间为5G。
分析-性能(以2000w月活为例):
- 1) 老系统push的平均QPS是2000;
- 2) 2000W/2000/60/2=83~=1小时20分钟,希望能够在12分钟内推送完毕(一个小时推送1亿的指标)。
难点分析:
- 1) 数据做到准实时,怎么算准实时;
- 2)2000千万的数据12分钟内推送完毕,QPS~=2.7w, 如何让性能提升13.5倍(2k提升到2.7w的并发)。
解决方案:
- 1) 数据的准实时:实时接收kafka日志消息,每分钟把清洗的数据进行合并;
- 2)需要存储的数据要素:用户的token信息(注意不是devicetoken);此token的活跃时间(时间戳);
- 3)用户数据存储选型。

最终选择redis的zset进行存储。
5.2 如何提高发送性能
首先分析之前之所以慢的原因:
- 1) 单线程发送;
- 2) 受到厂商通道的限制,单接口耗时100ms+(IOS通道)。
解决方案:
- 1)区分安卓、IOS单独发送,原始程序只负责从redis拿到数据后拼装成固定结构(简单拼接操作速度很快);
- 2)把数据推送到MQ中(可以不用MQ吗?);
- 3)多个消费订阅者,进行消费(容易扩展),通过厂商 通道推送出去。
注意:iOS通道,我们用的pushy开源工具,特定情况下无法持续推送消息,需要定时检查,重新创建通道。
最后的效果:push推送的QPS达到3w+,推送能力提升的同时,也引发了以下问题。
5.3 业务服务器扛不住瞬时流量
问题描述:当push的推送能力上去了之后, 用户的瞬时访问问题随之而来
- 1)瞬时的流量高峰,导致超时增多;
- 2)部分请求到达性能瓶颈,超时增多,页面打不开~,见下图。
push落地效果:
解决办法:
- 1)最简单的办法:加机器;
- 2)业务接口多线程、服务治理,消峰(ratelimit);
- 3)app核心功能增加缓存,保证不会出现白屏的情况;
- 4)减少活动路径。(一般push都会落地到某一个活动页面。但是正常打开push,都会先进入首页,在跳转到活动页面。给push的消息增加特殊埋点,如果是此类push消息,就直接 跳转到特定页面,减少中间环节。)
6、AB实验室
问题描述:有一天晚上9点推送了一个运营类的push,发现居然点击率超级高,是文案优秀?还是流量高峰?
要求:存在多个推送文案,系统能够择优选择点击率最好的进行推送?
解决方式:加入AB测的能力,先进行少量用户推送,根据AB的效果,择优推送.
7、整合全部手机厂商级ROOM推送通道
新的问题:之前安卓的通道我们仅有小米通道+个推(个推达到率一般,做托底), 如果我们向华为手机推送消息,也是通过小米通道是很难到达的。
要求:
- 1)希望能够把大厂的厂商通道都接进来;
- 2)推送的消息能够根据用户最后登录的通道进行优化推送;
- 3)速度不能慢下来。
解决方式:
- 1) 搭建tokens服务,能够批量判定devicetoken的最后使用的厂商(需要依赖转转客户端上报);
- 2) 分库分表的方式进行存储;
- 3) 数据热备到缓存中。
效果:当年统计能够提高10%的达到率。
8、消息送达监控
一般的监控维度包含:
- 1)产品线:转转、找靓机等等;
- 2)客户端:安卓、IOS;
- 3)指标:发送、到达、点击的数量和比例;
- 4)数据对比:模板、周期;
- 5)通道:小米、华为、vivo、apns。
9、 本文小结
现状:
- 1) 推送月活10分钟;
- 2) 支持暂停、预览,实时查看推送数据量;
- 3) 支持提前AB看效果;
- 4) 支持不在线,微信通知;
- 5) 支持防打扰;
- 6) 支持优先级和厂商高优通道。
提高速度:预加载+缓存+多线程+合理的数据结构+批量处理+合理布局+特殊埋点。
折中方案:异步上传、限流控制、降级处理、分层解耦、补偿通知。
10、 参考资料
[1] 极光推送系统大规模高并发架构的技术实践分享
[2] 魅族2500万长连接的实时消息推送架构的技术实践分享
[3] 专访魅族架构师:海量长连接的实时消息推送系统的心得体会
[4] 基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)
[5] 一个基于长连接的安全可扩展的订阅/推送服务实现思路
[6] 实践分享:如何构建一套高可用的移动端消息推送系统?
[7] Go语言构建千万级在线的高并发消息推送系统实践(来自360公司)
[8] 腾讯信鸽技术分享:百亿级实时消息推送的实战经验
[9] 京东京麦商家开放平台的消息推送架构演进之路
[10] 技术干货:从零开始,教你设计一个百万级的消息推送系统
[11] 爱奇艺WebSocket实时推送网关技术实践
[12] 喜马拉雅亿级用户量的离线消息推送系统架构设计实践
[13] 消息推送技术干货:美团实时消息推送服务的技术演进之路
[14] 揭秘vivo百亿级厂商消息推送平台的高可用技术实践
[15] 得物从零构建亿级消息推送系统的送达稳定性监控体系技术实践
[16] B站千万级长连接实时消息系统的架构设计与实践
(本文已同步发布于:http://www.52im.net/thread-4852-1-1.html)