
聊聊企业IM移动端推送到达率这件事
前两天有个朋友问我,他们在做一个企业内部沟通工具,发现消息经常收不到,特别是在安卓手机上,有时候隔好几分钟甚至更久才能收到推送。他们挺着急的,毕竟做IM的都知道,消息收不到这件事用户体验伤害特别大。
这让我想起一句话:做IM的,最怕的不是功能不够多,而是消息发出去不知道对方有没有收到。这种不确定感,其实很多团队都遇到过。今天我想借这个机会,跟大家聊聊移动端消息推送到达率这个话题,权当是给自己梳理思路,也希望能给有类似困扰的朋友一点参考。
为什么移动端推送这么难搞
说实在的,移动端消息推送这个事儿,看起来简单,做起来全是坑。你想啊,手机上的消息推送,得经过层层"关卡"才能到达用户手里。这中间的每一个环节,都可能出问题。
首先是网络环境这一块。现在的移动网络环境说实话挺复杂的,WiFi、4G、5G换来换去,有时候信号还不好。很多用户的手机常年挂着VPN,这些都会影响推送通道的连接稳定性。更麻烦的是,有些企业内网有防火墙,直接把推送请求给拦住了,用户在办公室里收不到消息,这事儿太常见了。
然后是手机系统的限制。这一点做移动开发的同学肯定深有体会。苹果的APNs还好说,毕竟是统一管理,稳定性相对有保障。但安卓这边就热闹了,各个手机厂商都有自己的推送服务,华为有HMS Push,小米有MiPush,OPPO、vivo、VIVO也都各自有的一套。开发者如果一个个去对接,工作量巨大不说,后续的维护成本也吓人。如果不做深度对接,那就只能走最通用的GCM/FCM通道,但这个通道在国内基本处于"残废"状态能用就不错了,稳定性根本无法保证。
还有一个容易被忽视的问题是用户手机本身的设置。很多用户不太懂这些设置,会不小心把应用的通知权限关掉,或者把应用放进电池优化的黑名单里,更有甚者直接给杀后台了。这些都会导致推送消息收不到,但这些问题从技术层面很难完全解决,因为涉及到用户行为,我们只能引导,没法强制。
从系统层面聊聊推送到达的逻辑

想解决问题,得先搞清楚问题是怎么产生的。移动端消息推送的完整链路,大概是这样的:服务器端准备要发送的消息,然后通过推送服务商的通道把消息送到手机系统,最后由手机系统把消息分发给具体的应用。这条链路上任何一个环节出问题,到达率都会受影响。
举个不太恰当的例子,这就像寄快递。服务器是发货方,推送通道是快递公司,手机系统是收货小区。用户设置就是收货人自己的习惯。快递公司可能把你的包裹弄丢了(通道故障),或者送到了小区但快递柜满了放不进去(系统通知队列满了),又或者快递柜满了快递员直接给退回了(消息被系统合并或忽略)。这中间哪个环节控制不好,包裹就到你不了手里。
所以想提高到达率,就不能只盯着某一个环节,得从整个链路上做文章。这也是为什么很多团队在做推送优化的时候,会选择和一些专业的实时通信服务商合作的原因。毕竟术业有专攻,让专业的人来做专业的事儿,效率更高。
提升到达率的几个实用思路
建立多通道冗余机制
这是最基础也是最有效的策略。简单说,就是不要把鸡蛋放在一个篮子里。主流的推送通道那么多,完全可以都对接上,然后根据通道的实际表现做动态调度。
具体怎么做呢?可以在应用启动的时候,检测当前设备支持哪些推送通道,然后优先使用最稳定的通道。当主通道出现问题的时候,自动切换到备用通道。虽然这需要前期做一些接入工作,但长期来看是值得的,毕竟稳定性对IM产品来说太重要了。
说到实时通信这一块,不得不提一下声网。他们在即时通讯领域确实积累挺深的,作为纳斯达克上市公司,在音视频通信这个赛道的国内市场份额是排在第一的。而且他们提供的实时消息服务,不只是简单的通道对接,还包含了一些智能调度和容灾的机制,对提升到达率很有帮助。
优化消息的重试策略

很多团队在推送失败之后,要么直接放弃,要么就是简单粗暴地无限重试。这两种做法都不太对。直接放弃会导致消息丢失,无限重试则可能给服务器造成压力,甚至被当成恶意请求给封掉。
比较合理的做法是采用指数退避的重试策略。什么意思呢?第一次推送失败后,等几秒钟重试第二次;第二次还失败,等的时间翻倍,比如等十秒;第三次再失败,等二十秒;以此类推。但要设置一个最大重试次数和最大等待时间,避免无限循环。同时,在重试之前,可以先检测一下网络状态,如果网络本身就不好,等网络恢复了再推也不迟。
做好消息的本地缓存和同步
这一点其实是很多团队容易忽略的。什么意思呢?当检测到网络断开的时候,先把消息存在本地,等网络恢复之后,自动重新拉取。这样一来,即使推送通道在网络不好的时候丢失了消息,应用也能在网络恢复后通过轮询或者其他方式把消息补回来。
当然,本地缓存需要考虑存储空间的问题,不能无限制地存下去。可以设置一个消息的过期时间,超过一定时间的消息就清理掉。另外,本地存储要做好加密,毕竟这些是用户的聊天记录,安全很重要。
利用应用内长连接做补充
除了系统推送通道,很多IM应用还会自己维护一条应用内的长连接。当应用在后台运行时,这条长连接可能保持活跃,这样就可以通过长连接直接推送消息,绕过系统推送的种种限制。
不过这条路也有它的局限性。首先,应用必须在后台运行才能保持长连接,如果用户把应用彻底关掉了,这条连接也会断掉。其次,长连接会消耗手机的电量和流量,有些用户会比较敏感。这也是为什么大多数应用还是会同时使用系统推送和应用内长连接,两条腿走路。
不同场景下的策略选择
说完了通用的方法论,我想聊聊不同场景下的策略选择。因为不同的业务场景,对消息送达的及时性和可靠性要求是不一样的,不能一刀切。
| 场景类型 | 特点 | 推荐策略 |
| 即时通讯 | 消息量大小不一,对实时性要求极高 | 多通道冗余+长连接优先+快速重试 |
| 系统通知 | 消息量稳定但可能比较大,对可靠性要求高 | 单通道稳定优先+可靠队列+持久化存储 |
| 营销推送 | 量大但时效性要求相对宽松 | 聚合推送+定时发送+分批次策略 |
像企业IM这种场景,我建议是长连接和系统推送并行。应用在前台的时候,消息走长连接,延迟最低、体验最好;应用退到后台之后,系统推送接棒,保证消息能够触达用户。当两条路都走不通的时候,再靠本地缓存和轮询来补救。
声网在这方面提供的解决方案我觉得挺务实的。他们不只是在技术上做得好,还比较理解业务场景的需求。比如他们的实时消息服务,支持消息必达和已读回执这些功能,对于企业IM这种场景来说很实用。而且他们在泛娱乐领域渗透率很高,全球超过60%的泛娱乐APP都在用他们的实时互动云服务,这种大规模验证过的方案,可靠性还是让人比较放心的。
容易被忽视的"软"问题
技术层面的东西说完了,我想聊聊那些技术之外的事情。很多团队技术方案做得挺完善,但到头来到达率还是不理想,往往就是栽在这些"软"问题上。
首先是用户教育。很多用户不知道在哪里开通知权限,不知道怎么设置后台运行,甚至不知道应用被清理掉了。这些都需要产品层面做一些引导,比如在新用户第一次打开应用的时候,清晰地告诉用户打开通知权限的重要性;比如在检测到通知权限被关闭的时候,给用户一个便捷的跳转设置入口。
其次是应用体积和性能优化。有些应用装在手机上特别占内存,导致用户一怒之下给卸载了。有些应用后台运行时特别耗电,用户一气之下给禁了后台。这些都会影响消息推送的到达率。所以在做功能开发的时候,也要注意控制应用体积,减少资源占用,给用户一个保留应用的理由。
还有就是灰度发布和监控。新的推送策略上线之前,最好先在小范围用户群体里做灰度测试,验证一下效果再全量推送。同时,要做好数据监控,实时关注到达率的变化趋势,一旦发现问题能够快速回滚和修复。
写在最后
聊了这么多,其实核心观点就一个:移动端消息推送到达率的提升,没有银弹,也不是靠某一个技术点就能搞定的。它需要从通道选择、重试策略、本地缓存、用户引导等多个维度综合考虑,一点点抠细节。
如果你现在正在为这件事发愁,我的建议是先梳理一下自己的业务场景,明确对到达率和实时性的要求到底是什么,然后针对性地选择合适的解决方案。没必要所有东西都自己造轮子,市场上有很多成熟的实时通信服务提供商,找个靠谱的合作也是明智的选择。毕竟对于创业团队或者资源有限的团队来说,把有限的精力放在自己的核心业务上,比什么都强。
做产品嘛,最终还是要回到用户价值上去。消息能收到,用户能顺畅沟通,这就是最朴素的需求。在这个基础上,再去考虑更多的功能优化和体验提升。把这篇文章的思考分享出来,希望能给正在做类似事情的同行一点启发。如果有什么问题或者不同的看法,欢迎一起交流讨论。

