亿级推送,得物是怎么架构的?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 :

免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备
免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,完成职业升级, 薪酬猛涨!加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷1)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷2)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷3)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领

免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取


亿级推送,得物是怎么架构的?

说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,很多小伙伴拿到一线互联网企业如阿里、网易、有赞、希音、百度、滴滴的面试资格。

最近,尼恩指导一个小伙伴简历,需要织入亮点项目、黄金项目。

前段时间,指导小伙写了一个《高并发消息推送项目》,帮这个小伙拿到 字节/汽车之家 等优质机会,并且帮他 喜提一个 “中间件王子offer” , 尼恩还对此案例进行了全面覆盘:

被裁不慌,9年小伙1个月喜提年薪60W offer,做中间件架构,爽歪了

所以说,《高并发消息推送项目》 是一个牛逼的项目。

为了帮助大家拿到更多面试机会,拿到更多大厂offer, 在此文之前,尼恩还专门有文章对 消息推送的架构进行介绍:

消息推送 架构设计

架构总是无止境的。

前段时间尼恩看到了一个非常优质的案例 《从0到1,亿级消息推送的稳定性保障》, 这个案例,是一个非常优质的案例, 也是是一个亿级推送的生产案例、工业案例。

尼恩对这个案例进行了深入研读/二次分析, 吸纳到咱们的架构体系里面来, 为大家的所用,用于尼恩指导大家做简历改造。

也一并把这个案例,收入咱们的 《尼恩Java面试宝典》V169版本《架构专题》,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到公号【技术自由圈】获取

此文的原创是得物技术的架构师暖树,并不是尼恩。 但是原文不是太好懂 ,尼恩仅仅以学习笔记的形式, 对原文做二次 学习, 把原因改造得尽量浅显易懂。

由于无法联系到作者本人,尼恩的学习和改造也没有获得作者的同意。

特别说明,如果得物技术或者作者暖树本人不同意 尼恩的学习改造, 可以发消息给尼恩, 立马就从尼恩的自媒体扯下来。

本文目录

推送的巨大价值

从用户的生命周期来看,消息推送对于提高 App 活跃度、提升用户粘性和用户留存率都起到了重要作用。

  • 提升新用户次日留存,低成本促活,对平台的短期留存率影响显著。

  • 提升老用户活跃度,push 可以通过外部提醒起到拉活的作用。

    很多内容平台类 App 的用户 push 首次启动占比可达 10%以上,因此 push 对 DAU 的增量贡献不容小觑。

  • 流失用户召回,当用户流失后,若 push 权限未关闭,通过消息推送的方式,有可能重新唤醒用户。

消息推送每天都在我们的手机上发生,如图所示,除非你的手机没有安装App或关闭了通知栏权限。

通用推送服务功能分析:

  • 发送通知

  • 对通知进行优先级排序

  • 根据客户的保存偏好发送通知

  • 支持单个/简单的通知消息和批量通知消息

  • 各种通知的分析用例

  • 通知消息的报告

一般来说,推送的渠道很多,包括的电子邮件、短信、聊天、钉钉、企业微信和其他公共社交应用:

  • 聊天 - 微信Wechat/QQ

  • 站内推送通知(移动设备和Web浏览器)

  • 站外推送通知(移动设备,APP没有开启)

  • 短信(如登录密码、营销活动)

  • 电子邮件

  • 钉钉

  • 企业微信

通用推送系统设计架构:

注意:请点击图像以查看清晰的视图!

推送非功能性需求(NFR):

  • 高性能: qps > 1W

  • 高可用性(HA): 99.99%

  • 低延迟: TP99 在10ms以下

  • 高扩展:可扩展/可插拔的设计,以便添加更多适配器和提供商,与所有通知模块的API集成以及与客户端和服务提供商/供应商的外部集成

  • 跨平台:支持Android/iOS移动设备和桌面/笔记本电脑的Web浏览器

  • 自伸缩:可在本地(VMware Tanzu)和 AWS、GCP 或 Azure 等公共云服务上扩展负载

推送的SLA 服务等级指标

SLA(Service-Level Agreement),也就是服务等级协议,指的是系统服务提供者(Provider)对客户(Customer)的一个服务承诺。

SLA(Service-Level Agreement)是衡量一个大型分布式系统是否“健康”的常见方法。在开发设计系统服务的时候,无论面对的客户是公司外部的个人、商业用户,还是公司内的不同业务部门,我们都应该对自己所设计的系统服务有一个定义好的 SLA。

因为 SLA 是一种服务承诺,所以指标可以多种多样。下面是四个常见的SLA指标 ,可用性、准确性、系统容量和延迟。

1. 可用性(Availability)

可用性指的是系统服务能正常运行所占的比例。

例如我们说要搭建一个”100%“的系统服务,也就意味我们要需要保证在任何时候这个系统都能运行,都说可用的,但实际这在现实中,是非常困难的,成本也是非常的高。

对于大部分的系统而言,能保证4个9的可用性(99.99%的可用性)就可以说这个系统是高可用的。

99.99%的可用性是指一天(60×60×24秒),只有8.64秒(60×60×24×0.0001秒)为不可用,一年就是大概有52.56分钟(8.64*365/60分钟)不可用。

99.99% 一天只有8秒左右的不可能用时间,这已经可用满足大部分系统的要求了。

2. 准确性(Accuracy)

准确性指的是我们所设计的系统服务中,是否允许某些数据是不准确或丢失,如果允许那么允许的百分比是多少?

不同系统对准确率都会有一个衡量的指标,大部分系统可以 用错误率来衡量。

错误率怎么计算呢?可以用导致系统内部错误有效请求数除以总的有效请求数而求得。

错误率=导致系统内部错误有效请求数/总的有效请求数

系统一分钟内收到的总的有效请求为100个,其中有10个导致系统内部错误,则我们可以认为错误率为10%

下面我们看下大公司中对系统错误率的对比

Google Cloud Platform 的SLA中,有着这样的定义:

每个月的错误率超过5%的时间要少于0.1%,以每分钟为单位来计算。

亚马逊AWS云计算平台对SLA的准确性定义为:

以每5分钟为单位,错误率不会超过0.1%。

那我们可以通过哪些途径来获取系统的准确性呢?大部分情况我们可以通过软件测试系统日志来判断。

3. 系统容量(Capacity)

在数据处理中,系统容量通常指的是系统能够支持的预期负载量是多少,一般会以每秒请求数为单位来表示。

我们常常听见某个系统的架构可以处理的QPS(Queries Per Second 系统每秒查询数)是多少或者RPS(Requests Per Second系统每秒请求数)是多少。

4. 延迟(Latency)

延迟指的是系统在收到用户的请求到响应这个请求的时间间隔

在定义延迟的SLA时,我们常常看到系统的SLA会有p95或者是p99这样的延迟声明。

这里的p指的是percentile(也就是百分比的意思),假设一个p95的系统延迟是1秒,那就表示100个请求里面有95个请求的响应时间是少于1秒的,而剩下的5个大于1秒。

对于消息推送而言,我们主要关注的是消息能否及时可靠的送达给用户,也就是 SLA 中关注的延迟(Latency)、准确性(Accuracy)和可用性(Availability)的问题。

得物推送背景和痛点

消息中心为得物 App 提供了强大、高效的用户触达渠道,推送对于得物 DAU 的贡献有可观的占比,每一条推送消息,这也就意味着都是一次与用户沟通的宝贵机会。

得物推送背景和痛点:

  • 延迟(Latency)

与用户主动点击的WEB场景不同,在推送场景,用户是被动参与的。

业务方对于推送的消息什么时候到达没有明确的心理预期。

在这里,可用性的度量是模糊的。

如何提升推送的低延迟,首先需要我们针对消息推送的链路单元耗时进行监控,然后对各个链路单元的耗时做针对性的优化,不断降低延迟。

  • 可用性(Availability)

消息推送的稳定性依赖于第三方的推送通道,而三方通道对于我们来讲就是个黑盒子。

如何提升推送的可用性(Availability),关键是要做到三方通道异常及时发现,并且及时止损,也是需要考虑的问题。

从以上两个维度来说,都需要对系统进行全面的监控。

得物推送的深度监控实践

目前消息中心针对实效性和稳定性的开发已经完成并初显成效,下面主要针对时效性和稳定性的监控做一些介绍。

监控系统架构图

监控分为三个维度:

  • 第一维度:全链路监控

  • 第二维度:厂商监控

厂商的监控代码要从主流程逻辑中解耦,通过旁路流程进行异步的监控。

每天有数亿的消息推送,在这种大规模推送背景下,异步的监控,就不会影响主流程的处理性能。

  • 第三维度:业务方监控

第一维度:全链路监控

1. 链路的拆分

首先,需要对全链路进行细粒度的拆分。 在拆分之前咱们先从宏观维度,看看 得物推送后台的 消息流转流程,宏观上包括 下面的四个阶段:

  • 业务发消息
  • 推送预处理编排
  • 目标通道接入
  • 目标通道完成消息推送

具体如下图:

如何做到全链路时效性的无死角监控?

首先,对消息推送的整个流程进行深入解耦,解耦出若干个独立的、可监控单元链路单元。

整个推送流程,主要会经历:

  • 推送鉴权

  • 用户查询

  • 防疲劳过滤

  • 防重复过滤等

这些业务单元,每个单元的逻辑的处理是相互独立且无依赖的,可以按照单元进行拆分,对每一个单元进行监控。

这样就可以做到拆分无遗漏,监控无死角,拆分后的具体链路单元如下:

2. 链路单元耗时的计算

具体的链路单元耗时逻辑的计算如下图:

每一个链路单元,都设计多个 核心时间节点,比如 操作开始时间,操作完成时间。

3. 链路单元指标的制定

既然需要监控的链路单元已经拆分明确了,那针对这些链路单元我们监控哪些指标才是有意义的呢。

目前消息推送高峰耗时较长,业务域对于消息的到达时间也没有心理预期,所以涉及另个核心指标:

  • 链路单元的推送耗时

  • 链路单元的推送量/阻塞量

链路单元耗时的计算公式:

  这一个操作完成时间  -   上一个操作完成的时间 ,

例如

防疲劳耗时=T7(antiFatigueConsumeTime)-T6(checkrepeatConsumeTime)

链路单元阻塞量的计算:

记录链路单元消息推送的瞬时阻塞量,

例如防疲劳链路单元阻塞量 =

 防疲劳的总量-防疲劳已经处理的量

链路单元的阻塞量,是度量是否有积压的核心指标,如果存在积压,就需要扩容。

当然,在大促期间,消息的推送量也会达到一个高峰,往往都存在积压问题,需要进行提前扩容。

考虑到消息推送是有优先级的并且区分单推和批量推,所以我们要针对不同的优先级和推送方式设置不同的标准,消息推送耗时的具体标准如下。

4. 全链路技术方案的实现

首先,要考虑高并发、高吞吐场景。

消息中心每天推送大量消息给得物用户,SLA 全链路监控,一定不嵌入主流程, 任何一个操作嵌入主流程中都可能导致消息推送的延迟。

这也就要求监控和主流程进行隔离,主流程的归主流程,SLA 的归 SLA。

SLA 监控代码从主流程逻辑中剥离出来,彻底避免 SLA 代码对主流程代码的污染。

SLA 逻辑技术方案的实现的要求:

  • 独立于推送业务的主流程进行异步计算,防止 SLA 监控拖垮整个主流程

  • 使用非入侵的方式,我们使用的是 Spring AOP注解的方式

SLA 逻辑技术方案的 技术方案:Spring AOP+Spring Event。

主要链路单元包括鉴权、风控、用户查询、防疲劳、防重复、厂商调用,通过链路单元拆分,一单出现指标异常,可以很快定位到异常发生的具体位置。

5. 全链路监控结果

时效性链路单元监控:

时效性链路单元告警:

消息推送实效性监控做完之后,实现了 指标化和预警化:

  • 指标化:关键链路单元耗时的指标化,

  • 预警化:对服务链路单元耗时异常可以及时感知,同时也完成了预警的对接

第二维度: 厂商推送监控

1. 监控指标制定

对 厂商推送监控, 主要涉及到三个核心指标:

  • 推送成功率
  • 回执成功率
  • 点击率

如果出现推送成功率跌零、回执成功率跌零、点击率的跌零, 就需要进行技术的预警,这种情况下整个推送通道都挂掉了,我们要及时通知厂商进行修复,

另外,如果没有跌零,是不是也要监控呢? 是的。

一般来说,厂商的推送成功率、回执成功率、点击率都稳定在一定的的区间。如果厂商推送的指标数据偏离这个区间则说明推送有异常,也要进行告警和排查。

厂商监控监控告警的维度大致如下:

对这些指标,可以通过 Prometheus+grafana指标平台,进行时序展示:

2. 厂商推送监控技术方案实现

在落地面,监控技术方案首先不能影响主流程中处理,

因为每天有数亿的消息推送,如果影响到核心流程,那么核心流程性能会大大降低。

所以,和第一个维度链路的监控类似,厂商的监控代码要从主流程逻辑中剥离出来,避免监控拖垮主流程,同样避免监控异常影响到推送的主流程。

如何解耦呢?这里使用的是有界内存队列实现。

3. 结果

消息推送厂商监控上线之后,可以及时感知到厂商推送的异常信息,对于厂商推送的异常和厂商规则的更改等可以做到及时的感知。

第三维度:业务方监控

这里涉及到业务方的调用速率、消息的发送数量(单条和批量发生)、成功比例进行监控和预警。

这里得物原文没有给出方案, 应该是有遗漏了。

得物推送监控带来的收益

1. 及时发现线上异常

监控上线后,能及时发现厂商的很多线上以上:

  • 推送线程关闭失败
  • 厂商推送跌零
  • 厂商营销消息规则更改
  • 厂商通道偶发不可用
  • 等问题

及时发现异常后,就可以做到了及时的止损。

  • 在时效性监控上线之后,发现了因厂商推送线程创建关闭失败导致线程数逐渐上升问题,避免了线上故障的发生。

  • 厂商异常导致推送跌零,监控发现后及时通知到厂商并止损。

  • 发现厂商营销消息规则更改的异常,

并及时经梳理各大厂商文档后,发现除了多个厂商通道在未来一个月内也会有规则的更改,消息平台团队对规则进行优化及时适应了厂商规则,接入厂商系统通道,做到了及时止损。

2. 帮助连接池和连接时间参数优化

通过全链路的有效性监控,发现了多个服务可以优化的点,

比如,发现多个厂商和推送链路单元在高峰推送时耗时较高,发现厂商推送 SDK 连接池和连接时间参数需要优化, 优化后消息推送整体的吞吐量实现了翻倍的提升。

得物推送监控总结

得物推送监控上线后,带来的收益还是比较可观的,

展望未来,后续可以从以下点丰富现有监控。

  • 后续将针对各个链路单元的推送异常、漏斗转化率、服务性能等做监控,进一步丰富消息平台的监控体系。

  • 后续将对推送的转化率问题进行监控

  • 后续将对卸载、屏蔽等指标也是我们需要监控的点,

总之,通过对业务指标进行扩展,及时感知推送的效果,做到精细化的管控。

说在最后:有问题找老架构取经

推送系统,是一个很黄金的系统。

如果写入简历,并且面试的时候能对答如流,如数家珍, 面试官会被你 震惊到、吸引到。

最终,让面试官爱到 “不能自已、口水直流”

offer, 也就来了。

在面试之前,建议大家系统化的刷一波5000页《尼恩Java面试宝典PDF》 ,里边有大量的大厂真题、面试难题、架构难题。很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

金三银四挪窝的黄金时期到了,建议大家简历上织入一个 《推送系统》, 当然如果不知道怎么织入,可以找尼恩来改简历、做帮扶。

遇到职业难题,找老架构取经, 可以省去太多的折腾,省去太多的弯路。尼恩指导了大量的小伙伴上岸,前段时间,刚指导一个40岁+被裁小伙伴,拿到了一个年薪100W的offer。

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

技术自由的实现路径:

实现你的 架构自由:

吃透8图1模板,人人可以做架构

10Wqps评论中台,如何架构?B站是这么做的!!!

阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了

峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?

100亿级订单怎么调度,来一个大厂的极品方案

2个大厂 100亿级 超大流量 红包 架构方案

… 更多架构文章,正在添加中

实现你的 响应式 自由:

响应式圣经:10W字,实现Spring响应式编程自由

这是老版本 《Flux、Mono、Reactor 实战(史上最全)

实现你的 spring cloud 自由:

Spring cloud Alibaba 学习圣经》 PDF

分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)

一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)

实现你的 linux 自由:

Linux命令大全:2W多字,一次实现Linux自由

实现你的 网络 自由:

TCP协议详解 (史上最全)

网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!

实现你的 分布式锁 自由:

Redis分布式锁(图解 - 秒懂 - 史上最全)

Zookeeper 分布式锁 - 图解 - 秒懂

实现你的 王者组件 自由:

队列之王: Disruptor 原理、架构、源码 一文穿透

缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)

缓存之王:Caffeine 的使用(史上最全)

Java Agent 探针、字节码增强 ByteBuddy(史上最全)

实现你的 面试题 自由:

4800页《尼恩Java面试宝典 》 40个专题

免费获取11个技术圣经PDF:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章