转转push的演化之路

一、简介

从0开始讲讲转转push系统的迭代过程,以及遇到的常见问题的解法。

顾名思义,push就是就是借助厂商通道把消息发送给用户的一种方式,一般用于用户的召回和活动触达,和IM(即时通信)还是有一些区别,不在此处赘述。

1.1 名词解释

业务属性: 运营、业务、功能类推送
推送范围: 月活、全量、定向推送、个性化推送
目标端:一般是安卓、ios客户端
通道:小米、华为、魅族、apns等手机厂商的常驻连接
token: 用于设备的唯一标识,由APP本身生成
devicetoken:用于推送的唯一标识,一般由厂商提供
推送量:推送消息的数量
到达率:消息到达手机的数量/推送量
点击率:用户点击率/推送量

1.2 现有架构

push系统

  • 现有的架构支持后台推送、业务推送以及个性化推荐推送。

后台推送
一般会有标准的格式,特点是时间短、推送量大,比如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)部分请求到达性能瓶颈,超时增多,页面打不开~,见下图

push落地效果

解决办法:
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),更多干货实践,欢迎交流分享~

猜你喜欢

转载自juejin.im/post/7125609655165779976