开发即时通讯 APP 时如何优化消息推送的到达率

开发即时通讯APP时如何优化消息推送的到达率

即时通讯开发这些年,我发现一个特别有意思的现象:很多团队在初期根本不把消息推送当回事,觉得"能发出去不就行了吗"。等用户量上来了,问题才一个个冒出来——用户投诉收不到消息、在线状态乱跳、消息延迟到让人怀疑人生。我自己也踩过不少坑,今天就把这些经验教训整理一下,跟大家聊聊怎么把消息推送的到达率做好。

先说个数据吧。行业内有个不成文的说法:推送到达率每下降1个百分点,用户的日活跃度可能就会跟着往下掉。这事儿我一开始也不信,后来跟几个朋友的产品对了一下数据,发现还真差不多。尤其在即时通讯这个场景下,消息收不到可比功能不好用严重多了——用户会直接觉得你"坏了",而不是"有待改进"。所以今天这篇文章,我想用一种比较接地气的方式,把消息推送这事儿给大家讲清楚。

到底什么是消息推送到达率

在展开讲优化方法之前,我觉得有必要先把几个概念说清楚。因为我见过太多团队在这些概念上含糊不清,导致后面的优化工作根本没法量化。

简单来说,消息推送的完整链条是这样的:服务器端生成消息、通过长连接或者推送通道发给设备、设备上的APP接收并展示。在这个过程中,有几个关键指标我们需要分清楚。

指标名称含义说明
发送成功率服务器成功把消息发出去的比例,受网络和服务器状态影响
通道到达率消息通过推送通道到达用户设备的比例,这一步经常出问题
APP接收率消息到达设备后,APP成功接收并处理的比例
最终展示率用户真正看到消息的比例,这才是我们最关心的

这几个指标是层层递进的关系。最终的到达率其实等于上面所有环节成功率的乘积。举个例子,如果发送成功率是99%、通道到达率是95%、APP接收率是98%、最终展示率是99%,那整体的到达率就是99%×95%×98%×99%,算下来大概只有91%。看起来每个环节都不错,但整体却有将近10%的消息用户根本收不到。

这也是为什么优化推送到达率不能只盯着某一个环节,得整个链路一起看。下面我会从设备层面、网络层面、推送机制、服务器端这几个维度,详细说说每个地方可能出什么问题,以及对应的解决方案。

为什么到达率总是不够高

手机系统那些"有意为之"的限制

先说安卓阵营。这两年各大手机厂商为了省电续航,一个比一个狠。你能想到的所有国内主流安卓手机品牌,都有自己的后台管理策略。有的叫"省电模式",有的叫"智能省电",本质上都是限制APP在后台的时候收不到消息。

我之前负责的一个项目就吃过这个亏。当时我们用的是普通的推送方式,结果小米、华为、OPPO、vivo这几个主流机型,后台消息的到达率普遍只有60%到70%。用户投诉说消息延迟十几分钟都是常态,尤其晚上睡觉的时候,第二天早上打开一看,消息一股脑全来了。

iOS这边情况稍微好一些,因为苹果有统一的APNs推送通道。但APNs也有自己的问题——它只保证消息能发到系统层面,不保证APP一定能收到。特别是在用户清理了APP后台进程的情况下,有些类型的数据推送确实会受到限制。

另外还有一个容易被忽视的问题:消息聚合。现在很多APP都会把多条消息合并成一条推送,一方面是为了用户体验,另一方面也是为了省电。但这个聚合机制如果处理不好,就会导致用户明明收到了通知,却看不到具体内容,或者干脆以为没收到消息。

网络环境的影响远超你想象

说完设备层面的问题,再聊聊网络。我发现很多团队在测试推送功能的时候,都是在良好的网络环境下进行的。但真实世界里,用户所处的网络环境要复杂得多。

举个真实的例子。我们在东南亚市场有个客户,他们发现印尼用户的消息到达率明显低于新加坡。一开始以为是服务器的问题,后来排查发现,印尼很多地区的网络基础设施确实不如新加坡稳定,尤其是移动网络经常断线重连。这就导致消息在传输过程中丢失的概率大大增加。

还有一种情况是NAT超时。很多企业内网、移动网络运营商都会对长连接进行NAT映射,而这个映射是有时间限制的。如果你的长连接在这个时间内没有数据交互,就会被运营商的设备强行断开。用户看起来网络是连着的,但长连接其实已经断了,消息自然收不到。

我们自己的做法是在印尼这种网络不太稳定的地方,会在客户端增加更激进的心跳策略,同时在服务器端实现更完善的重试机制。后来把到达率从原来的80%左右提升到了95%以上,效果还是比较明显的。

推送通道的选择很有讲究

关于推送通道,我看到很多团队的做法是只用一种方式,要么全部走长连接,要么全部走推送平台。这样做的好处是简单,但问题在于单一通道的到达率天花板是有限的。

目前行业内比较主流的做法是"长连接+厂商推送+公有推送"的多通道策略。长连接用来处理实时性要求高的消息,比如打字状态、已读回执这些;厂商推送通道就是前面说的APNs和各大安卓厂商的系统级推送;公有推送则是像Firebase Cloud Messaging这样的跨平台服务。

但多通道策略也有它的问题:成本、维护复杂度、消息去重。特别是消息去重,同一条消息如果同时通过多个通道发出去,用户可能会收到重复的通知,这体验就很差了。所以你需要在协议层面做唯一性标识,在客户端做消息去重逻辑。

这里我给大家一个建议:先用长连接发送,长连接不通的时候降级到厂商推送,厂商推送也失败的话再考虑公有推送。这样既能保证大部分情况下的到达率,又不会让成本失控。

声网在实时消息领域的实践

说到消息推送,就不得不提我们声网在实时通讯领域这些年积累的经验。作为全球领先的实时音视频云服务商,我们在消息推送这个环节也做了很多针对性的优化。

声网的实时消息服务采用的是"全球端到端延迟小于600毫秒"的实时架构。这个数字看起来简单,背后其实做了大量的工作。首先我们在全球部署了多个数据中心,通过智能路由选择最优的网络路径。其次,针对不同地区的网络特点,我们专门优化了传输协议,比如在网络不太稳定的东南亚地区,我们会使用更激进的重传策略,在网络良好的地区则更多地考虑带宽效率。

在通道选择上,声网支持多通道智能切换。我们会实时监控各个通道的成功率,当某个通道的到达率下降时,自动切换到备选通道。这个切换过程对用户是透明的,他不会感知到任何变化,消息该到还是到了。

还有一个我觉得很实用的功能是离线消息的可靠存储和推送。用户在离线期间产生的所有消息,声网都会帮开发者可靠地存储起来,等用户上线后再按顺序推送给用户。这个过程中我们做了很严格的去重和排序逻辑,保证用户不会收到重复消息,也不会出现消息乱序的情况。

对于需要出海的项目,声网的一站式出海解决方案也非常有帮助。我们在全球热门出海区域都有节点部署,本地化的技术支持团队也能帮助开发者快速解决当地市场遇到的问题。像东南亚、中东、拉美这些地区,网络环境、设备碎片化程度都比国内复杂,有经验丰富的团队支持会少走很多弯路。

开发者应该怎么具体做

建立完善的消息分级机制

我发现很多团队在发送消息的时候,不管什么类型、什么重要程度,都是一样的处理方式。这样做不仅浪费资源,还会影响重要消息的到达率。

比较好的做法是给消息分级。比如可以分为三个等级:重要消息、普通消息、低优先级消息。重要消息比如用户收到新消息、好友请求这些,需要用最高优先级的推送方式;普通消息比如点赞、评论通知,可以适当降级处理;低优先级消息比如系统公告、运营活动,可以做聚合推送,甚至在服务端做一些限流。

分级之后,你可以在服务端配置不同的重试策略和推送策略。重要消息多重试几次、多用几个通道;普通消息适可而止;低优先级消息甚至可以不做重试,这样既能保证重要消息的到达率,又能控制服务器成本和推送对用户的打扰。

客户端的重试和本地缓存

客户端这边也有一些事情可以做。比如在发送消息的时候,如果遇到网络错误,不要立即放弃,而是要在本地做缓存,等网络恢复后自动重试。

这个本地缓存需要考虑几个问题。首先是缓存大小的限制,不能无限缓存下去,否则用户的存储空间会被吃光。其次是缓存的清理策略,太久远的消息就没必要再发了,可以直接丢弃。最后是用户可见性,要让用户知道自己发的消息正在重试中,比如在界面上显示"发送中..."的状态。

对于接收端来说,本地缓存同样重要。如果一条消息因为各种原因暂时没能展示给用户,比如用户当时在打电话、或者APP在前台处理其他事情,等这些情况解除之后,APP应该自动把消息展示出来,而不是一直藏着。

用户在线状态的准确管理

在线状态这个功能,看起来简单,其实做好很难。我见过不少产品的在线状态要么更新不及时,要么经常跳变,用户体验很糟糕。

这里的核心问题是如何判断"在线"。最简单的办法是看长连接是否存活,但这个不太准确,因为长连接可能还连着,但用户其实已经把APP切到后台了。更好的做法是结合APP的前后台状态、屏幕是否点亮、用户是否有交互行为一起来判断。

声网的解决方案里有一个"多维度状态感知"的能力,可以帮助开发者更准确地判断用户的真实在线状态。这个能力对于1V1社交、语聊房、视频相亲这些场景特别重要,因为在这些场景下,用户对实时性的要求非常高,在线状态不准确会直接影响使用体验。

监控和告警体系不能少

最后我想强调的是监控体系。很多团队是等产品出问题了才知道,但实际上等到用户投诉的时候,往往已经有很多用户受到影响了。

建议从消息产生的全链路去采集监控数据:发送端成功率、通道到达率、客户端接收率、最终展示率。每个环节的异常都应该有告警,比如某个区域的消息到达率突然降到90%以下,就应该有人去排查原因。

监控数据除了用来发现问题,还可以用来指导优化。比如你发现某个特定型号的手机推送到达率特别低,就可以针对性地做适配优化;某个时间段的消息延迟特别大,就可能是那个时段的网络或者服务器压力太大了。

写在最后

优化消息推送到达率这个事儿,说起来都是细节,但每一个细节都会影响到最终的用户体验。我自己这么多年做下来,最大的感触就是:不要假设任何环节是可靠的。从服务器到客户端,从网络到设备,每一个环节都可能在某个意想不到的时刻出问题。你能做的,就是把这些环节都考虑进去,每一个都做好冗余和容错。

如果你正在开发即时通讯相关的应用,或者遇到了推送到达率的问题,可以了解一下声网的实时消息服务。我们在音视频和实时通讯领域深耕多年,服务过全球超过60%的泛娱乐APP,积累了丰富的经验和成熟的技术方案。无论是国内还是出海市场,应该都能帮到你。

今天就聊到这里,如果有什么问题,欢迎大家一起讨论。

上一篇开发即时通讯APP时如何实现消息的举报分类
下一篇 实时消息SDK的设备接入的鉴权机制

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱:

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

手机访问
手机扫一扫打开网站

手机扫一扫打开网站

返回顶部