一、简介
从0开始讲讲转转push系统的迭代过程,以及遇到的常见问题的解法。
顾名思义,push就是就是借助厂商通道把消息发送给用户的一种方式,一般用于用户的召回和活动触达,和IM(即时通信)还是有一些区别,不在此处赘述。
1.1 名词解释
业务属性: 运营、业务、功能类推送
推送范围: 月活、全量、定向推送、个性化推送
目标端:一般是安卓、ios客户端
通道:小米、华为、魅族、apns等手机厂商的常驻连接
token: 用于设备的唯一标识,由APP本身生成
devicetoken:用于推送的唯一标识,一般由厂商提供
推送量:推送消息的数量
到达率:消息到达手机的数量/推送量
点击率:用户点击率/推送量
1.2 现有架构
- 现有的架构支持后台推送、业务推送以及个性化推荐推送。
后台推送:
一般会有标准的格式,特点是时间短、推送量大,比如8点秒杀活动。
业务推送 :
一般都是业务触发,特点是实时性强、优先级高,如订单支付消息。
个性化推送:
经常会和用户画像相关,特点是策略复杂、内容多样,需要有风控管理,如猜你喜欢等推荐策略。
二、项目迭代的过程
2.1 缘起: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) 上传和数据处理分开(我们当时是边上传,边解析文件比较慢)
2.2 重大节日,希望能够通知到近期的活跃用户
2.2.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)需要存储的数据要素
a) 用户的token信息(注意不是devicetoken)
b) 此token的活跃时间(时间戳)3)用户数据存储选型
场景 | 描述 | redis的Zset | MYSQL数据库 |
---|---|---|---|
数据初始化 | 批量写入全量数据 | 大数据系统直接导入 | 大数据系统直接导入 |
增加 | 准实时新增用户token | 直接写入 | insertOrUpdate |
更新 | 更新用户 | 直接覆盖 | insertOrUpdate |
删除 | 删除大于90天的token | 简单 | 复杂 |
批量读性能 | 获取用户集合(2000kw月为例) | 20s | 60s |
单key读性能 | 根据token,获取用户其他信息 | 3w+ | 2w |
扩容能力 | 是否能够快速扩容 | 是 | 否 |
最终选择redis的zset进行存储
4)如何提高发送性能
首先分析之前之所以慢的原因:
1) 单线程发送
2) 受到厂商通道的限制,单接口耗时100ms+(IOS通道)
解决方案:
1)区分安卓、IOS单独发送,原始程序只负责从redis拿到数据后拼装成固定结构(简单拼接操作速度很快)
2)把数据推送到MQ中(可以不用MQ吗?)
3)多个消费订阅者,进行消费(容易扩展),通过厂商 通道推送出去。
注意:IOS通道,我们用的pushy开源工具,特定情况下无法持续推送消息,需要定时检查,重新创建通道
- 最后的效果:
push推送的QPS达到3w+,推送能力提升的同时,也引发了以下问题。
2.2.2 业务服务器扛不住瞬时流量
问题描述:
当push的推送能力上去了之后, 用户的瞬时访问问题随之而来
1)瞬时的流量高峰,导致超时增多
2)部分请求到达性能瓶颈,超时增多,页面打不开~,见下图
解决办法:
1)最简单的办法:加机器
2)业务接口多线程、服务治理,消峰(ratelimit)
3)app核心功能增加缓存,保证不会出现白屏的情况
4)减少活动路径。(一般push都会落地到某一个活动页面。 但是正常打开push,都会先进入首页,再跳转到活动页面。 给push的消息增加特殊埋点,如果是此类push消息,就直接 跳转到特定页面,减少中间环节。)
2.3 AB实验室
-
问题描述:
有一天晚上9点推送了一个运营类的push,发现居然点击率超级高,是文案优秀?还是流量高峰?
-
要求:
1)存在多个推送文案,系统能够择优选择点击率最好的进行推送? -
解决方式:
1) 加入AB测的能力,先进行少量用户推送,根据AB的效果,择优推送
2.4 多通道来临
-
新的问题:
之前安卓的通道我们仅有小米通道+个推(个推达到率一般,做托底), 如果我们向华为手机推送消息,也是通过小米通道是很难到达的。 -
要求:
1)希望能够把大厂的厂商通道都接进来
2)推送的消息能够根据用户最后登录的通道进行优化推送
3)速度不能慢下来 -
解决方式:
1) 搭建tokens服务,能够批量判定devicetoken的最后使用的厂商(需要依赖转转客户端上报)
2) 分库分表的方式进行存储
3) 数据热备到缓存中 -
效果:
1) 当年统计能够提高10%的达到率2.5 实时监控
一般的监控维度包含:
产品线:转转、找靓机等等
客户端:安卓、IOS
指标: 发送、到达、点击的数量和比例
数据对比: 模板、周期
通道: 小米、华为、vivo、apns
三、总结
现状:
1) 推送月活10分钟
2) 支持暂停、预览,实时查看推送数据量
3) 支持提前AB看效果
4) 支持不在线,微信通知
5) 支持防打扰
6) 支持优先级和厂商高优通道
提高速度:
预加载+缓存+多线程+合理的数据结构+批量处理+合理布局+特殊埋点
折中方案:
异步上传、限流控制、降级处理、分层解耦、补偿通知
作者简介
王计宽,转转平台业务负责人。
转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。
关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~