从 0 到 1,亿级消息推送的稳定性保障 | 得物技术

语言: CN / TW / HK

1 消息推送简介

1.1 什么是消息推送

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

 

1.2 消息推送的价值

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

 

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

  • 提升老用户活跃度,push 可以通过外部提醒起到拉活的作用。很多内容平台类 App 的用户 push 首次启动占比可达 10%以上,因此 push 对 DAU 的增量贡献不容小觑。

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

2 背景和痛点

消息中心为得物 App 提供了强大,高效的用户触达渠道,其中 push 对于得物 DAU 的贡献有可观的占比,这也就意味着每一条推送消息都是一次与用户沟通的宝贵机会,所以推送的稳定性成为我们关注的首要问题,那么我们遇到的以下痛点就亟待解决。消息中心没有明确消息推送的耗时标准,业务和技术之间存在 gap,业务方对于推送的消息什么时候到达没有明确的心理预期。从技术上来讲消息推送各个节点的耗时不明确,无法对各个节点的耗时做针对性的优化,这也就需要我们针对消息推送的节点耗时进行监控。消息推送的稳定性依赖于第三方的推送通道,而三方通道对于我们来讲就是个黑盒子,如何做到三方通道异常及时发现并止损也是需要考虑的问题。在我们正常的迭代过程中有时候不可避免的会出现些异常或者有坏味道的代码,这些问题能不能及时发现、及时止损,能不能及时告警出来。

3 监控的实践

3.1 SLA 监控简介

SLA(Service-Level Agreement),也就是服务等级协议,指的是系统服务提供者(Provider)对客户(Customer)的一个服务承诺。这是衡量一个大型分布式系统是否“健康”的常见方法。在开发设计系统服务的时候,无论面对的客户是公司外部的个人、商业用户,还是公司内的不同业务部门,我们都应该对自己所设计的系统服务有一个定义好的 SLA。因为 SLA 是一种服务承诺,所以指标可以多种多样。最常见的四个 SLA 指标,可用性、准确性、系统容量和延迟。

 

对于消息推送而言,我们主要关注的是消息能否及时可靠的送达给用户,也就是 SLA 中关注的时效性和稳定性的问题。目前消息中心针对实效性和稳定性的开发已经完成并初显成效,下面主要针对时效性和稳定性的监控做一些介绍。

 

3.2 系统架构图

3.3 时效性监控

3.3.1 节点的拆分

 

如何做到时效性的无死角监控,那么我们就要对消息推送的整个流程进行拆分,把整个流程拆分成若干个独立且无依赖的可监控节点。从消息系统流转图中可以看到,整个推送流程是清晰明了的,消息的的推送主要会经历推送鉴权、用户查询、防疲劳过滤、防重复过滤等的逻辑处理,考虑到每个业务逻辑的处理是相互独立且无依赖的,那我们就可以根据具体的业务处理逻辑进行节点的拆分,这样就可以做到拆分无遗漏,监控无死角,拆分后的具体节点如下:

 

3.3.2 节点耗时的计算

具体的节点拆分逻辑和耗时逻辑的计算如下图:

 

 

备注:节点耗时的计算:记录节点消息推送到达的时间,并计算节点推送耗时,例如防疲劳耗时=T7(antiFatigueConsumeTime)-T6(checkrepeatConsumeTime)节点阻塞量的计算:记录节点消息推送的瞬时阻塞量, 例如防疲劳节点阻塞量 = 防疲劳的总量-防疲劳已经处理的量

3.3.3 节点指标的制定

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

 

  • 目前消息推送高峰耗时较长,各业务域对于消息的到达时间也没有明确的心理一个预期,另外消息中心也无法感知推送在整个链路各个节点的耗时情况,无法针对节点耗时做到有针对性的优化,所以节点的推送量和推送耗时就是我们需要重点关注的指标。

  • 节点的阻塞量可以让我们及时感知到推送中存在的积压问题,在大促期间,消息的推送量也会达到一个高峰,消息目前是否有堆积,处理的速度是否跟的上,是否需要临时扩容,那么节点的阻塞量就成了一个比较有意义的参考指标。

 

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

 

3.3.4 技术方案的实现

为了能感知到消息推送中发生的异常和耗时情况,这就需要我们标准化监控指标和监控的节点。其中耗时指标可以感知节点的耗时和代码的坏味道,阻塞量可以监控到节点的堆积情况,推送成功率可以感知节点的推送异常等。另外节点拆分后我们可以很快定位到异常发生的具体位置,经过拆分监控的主要节点包括鉴权、风控、用户查询、防疲劳、防重复、厂商调用等。

 

另外消息中心每天推送大量消息给得物用户,SLA 监控任何一个操作嵌入主流程中都可能导致消息推送的延迟。这也就要求监控和主流程进行隔离,主流程的归主流程,SLA 的归 SLA,SLA 监控代码从主流程逻辑中剥离出来,彻底避免 SLA 代码对主流程代码的污染,这也就要求 SLA 逻辑计算需要独立于推送业务的主流程进行异步计算,防止 SLA 监控拖垮整个主流程,那么 Spring AOP+Spring Event 就是最好的实现方式 。

3.3.5 结果

消息推送实效性监控做完之后,对服务节点耗时异常可以及时感知,同时也完成了关键节点耗时的指标化,可以明确的看到所有节点在各个时间的耗时情况,同时也对消息推送针对各个节点的的优化起到了指导作用。时效性节点监控:

 

 

时效性节点告警:

 

3.4 厂商推送监控

3.4.1 监控指标制定

消息推送接入的有多个推送通道,如何做到对这些通道做到无死角的监控,及时感知呢。

 

  • 在做厂商监控之前,我们就已经遇到了厂商通道推送跌零的情况,这种情况下整个推送通道都挂掉了,我们要及时通知厂商进行修复,所以厂商推送跌零告警和厂商余量监控是必须的。

  • 从现有数据来看,厂商的推送成功率、回执成功率、点击率都稳定在一定的的区间。如果厂商推送的指标数据偏离这个区间则说明推送有异常,所以推送成功率、回执成功率、点击率的监控是必须的。

  • 另外从业务请求发送的用户数来看,每天的消息推送基本是稳定的,相对应的厂商的回执数量和点击数量也是稳定的,那么对厂商推送成功的数量,回执的数量和点击的数量监控也有一定的参考意义。

 

业务侧请求发送的用户数:

 

 

厂商监控告警:

 

3.4.2 技术方案实现

厂商每天有数亿的消息推送,这也就意味着厂商的监控不能嵌在主流程中处理。厂商的监控代码要从主流程逻辑中剥离出来,避免监控拖垮主流程,同样避免监控异常影响到推送的主流程。针对厂商推送的监控,目前使用的是有界内存队列实现。

 

3.4.3 结果

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

 

 

4 带来的收益

4.1 异常的及时发现

监控上线后及时发现了发现了厂商推送线程关闭失败,厂商推送跌零、厂商营销消息规则更改、厂商通道偶发不可用等问题,并做到了及时的止损。

 

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

 

 

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

 

 

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

 

 

4.2 服务性能的提升时效性监控上线后发现了多个服务可以优化的点,其中多个厂商和推送节点在高峰推送时耗时较高,很明显节点耗时和厂商推送 SDK 连接池和连接时间参数需要优化。优化后消息推送整体的吞吐量实现了翻倍的提升。

5 展望未来

由于时间问题,目前消息监控只做了时效性和厂商推送稳定性相关的监控,但是监控上线后带来的收益还是比较可观的,可以预见的是监控的构建在未来必将带给我们更大的收益,后续我们可以从以下点丰富现有监控。

 

  • 考虑到业务预的推送量和推送时间是稳定的,那么我们可以针对业务维度添加推送数据的监控,及时感知上游推送数据的变化。

  • 其次我们可以针对各个节点的推送异常、漏斗转化率、服务性能等做监控,进一步丰富消息平台的监控体系。

  • 对于消息推送来讲也要考虑推送的转化率问题,那么卸载、屏蔽等指标也是我们需要监控的点,通过这些业务指标及时感知推送的效果,做到精细化的管控。

6 总结

消息平台监控上线后带来的收益还是比较可观的,包括多次异常的及时发现和止损,还有发现多个个可以优化的性能点,实现了服务高峰吞吐量的翻倍,同时也解决了我们现在遇到的以下痛点。

 

  • 时效性明确的给到了不同优先级的耗时标准,避免了业务和技术之间的 gap,业务方对于推送的耗时也有了明确的心理预期。

  • 时效性使得节点耗时的性能问题可以一目了然,通过对现有节点耗时问题的优化,消息服务的吞吐量实现了翻倍的提升。

  • 厂商稳定性监控使得厂商异常可以及时感知,其中厂商稳定性监控上线后发现多起厂商推送的异常,并做到了及时的解决和止损。

  • SLA 时效性和厂商稳定性上线后,消息中心可以及时感觉到推送链路的异常和代码的坏味道,特别是对于新上线的代码,如果存在异常可以及时感知。