1、引言
本文内容来自vivo互联网服务器团队李青鑫在“vivo开发者大会”现场的演讲内容整理而成(现场演讲稿可从本文末附件中下载)。
本文将要分享的是手机厂商vivo的系统级推送平台在架构设计上的技术实践和总结。这也是目前为止首次由手机厂商分享的自建系统级推送平台的技术细节,我们也得以借此机会一窥厂商ROOM级推送通道的技术水准。
2、关于作者
李青鑫,vivo互联网服务器团队架构师。
3、为什么需要消息推送
消息推送对于移动端APP来说,是很常见的业务特征,比如新闻APP中的最新资讯、社交应用中的系统通知、IM即时通讯应用的离线聊天消息等等。
可以说,没有消息推送能力,APP就失去了实时触达的能力,对于一个应用来说,它对用户的“粘性”将大大下降。而对于用户来说,信息实时获取的能力也将大大降低,用户体验也将大幅下降。
4、消息推送的技术障碍
以我们日常最常见的IM应用来说,离线消息的推送是必备能力。
但随着Android系统的不断升级,离线推送已经不单单是一个后台服务加长连接那么理所当然了。
对于早期的Android系统来说,想要实现IM的离线消息推送并不困难,搞个后台服务再加上socket长连接就算是齐活了。
但随着Android系统的升级,针对后台进程和网络服务限制不断加码,为了继续实现离线消息的推送,开发者们不得不跟系统斗志斗勇,搞出了各种保活黑科技,比如:Android4.0之后的双进程守护、Android6.0及之后的防杀复活术、以及发展到后来的腾讯TIM进程永生技术,一时间群魔乱舞、无比风骚(有兴趣的同学,可以读读《Android进程永生技术终极揭秘:进程被杀底层原理、APP应对被杀技巧》这篇针对所有保活黑科技的总结性文章)。
随着Andriod9.0的到来,基本从系统上堵死了各种保活黑科技的活路(详见《AndroidP正式版即将到来:后台应用保活、消息推送的真正噩梦》),各Android厂商的ROOM系统级推送通道也应运而生——华为推送、小米推送、魅族推送、OPPO推送、vivo推送,一时间从用户的噩梦(保活黑科技对用户困扰很大)变成了开发者的恶梦并持续至今(想要做好IM离线推送,如今的IM开发者们不得不一家家对接各手机厂商的离线推送,你说烦不烦)。
也别跟我说为什么不用Android官方的FCM服务(在国内这链接你能打开算我输,至于为什么,你懂的。。。),也别我跟提那个统一推送联盟(4、5年过去了,看样子还要继续等下去)。
于是,为了继续搞定离线消息推送,IM的开发者们目前只有两条路可选:
1)举白旗向系统投降,放弃保活黑科技,直接引导用户手动加白名单(详见《Android保活从入门到放弃:乖乖引导用户加白名单吧》);
2)一家一家对接各厂商的系统级推送通道(华为、小米、魅族、OPPO、vivo,悲剧的是,有些小众厂商并没自建推送的能力)。
随着Android系统对于开发者保活黑科技的“堵”,手机厂商们搞出自家的系统级推送通道来“疏”,也算是理所当然。而这些厂商之中,vivo的系统级推送通道出现的算是比较晚的。
本篇文章的余下技术内容,算是目前为止首次由手机厂商分享的自建系统级推送平台的技术细节,我们一起来学习。
5、从技术角度了解推送平台
推送平台是做什么的?
从技术的角度上来看,推送平台就是一个通过TCP长连接,将消息发送给用户的平台。所以推送平台的本质其实就是借助网络通道,将消息发送到用户设备上。
大家日常都收到过快递通知吧!当快递员将快递放到快递柜中,快递后台就会自动推送一条消息,通知你有快递。我相信,如果你是一位运营人员,你也会喜欢这种自动下发消息高效的方式。
大家感兴趣的,可以通过vivo开放平台入口,选择消息推送来更进一步了解更多技术细节,这里就不做展开了。
6、短连接与长连接
消息推送平台的本质,就是通过长连接将内容、服务、用户连在一起,将内容分发给用户,为终端设备提供实时、双向通信能力。
这里有个概念长连接,那么什么是长连接?
所谓的长连接就是:客户端与服务端维持的一条、在相对较长的时间里、都能够进行网络通信的网络连接(比如:基于TCP的长连接)。
为什么我们要采用长连接而不是短连接作为平台底层的网络通信?
先来看看短连接下消息下发的场景:使用短连接的方式就是轮询,即客户端定时的去询问后台有没有设备A的消息,当有设备A的消息时后台返回对应的消息,可能很多情况下都是无功而返,浪费流量。当后台有消息需要发送给设备A时,因为设备A没有过来取导致消息无法下发。
而使用长连接:当有设备A的消息时后台直接发送给设备A而不用等设备A自己过拉取,所以长连接让数据交互更加自然、高效。
7、业务需求驱动架构升级
对于系统的技术架构来说,它是动态的,不同阶段都可能会发生变化。而推动架构进行演进的推力,主要来自于业务需求,一起来回顾,平台的业务发展历程。
自年立项以来,随着业务量增长,不断为系统添加功能特性,丰富整个系统的能力使其满足不同的业务场景需求。比如支持内容完全审核、支持IM、支持IoT、支持WebSocket通信等。
从图上可以看到,业务量几乎每年都有几十亿的增长,不断攀高,给系统带来了挑战,原有的系统架构存在的问题,也逐渐浮出水面,比如延迟、性能瓶颈。
架构服务于业务,年之前我们平台所有服务都放在云上,但是依赖的其他内部业务部署在自建机房。
随着业务量增长与自建机房的数据传输,已经出现了延迟的问题,并且在逐渐恶化,不利于我们平台功能的拓展。
所以在年下半年,我们对部署架构进行调整:将所有核心逻辑模块都迁移到自建机房,架构优化之后,数据延迟问题得到彻底解决,同时也为架构进一步演进奠定了基础。从上面的图中可以看到我们接入网关也进行优化三地部署。
为什么要进行三地部署而不是更多区域部署呢?
主要基于以下三点考虑:
1)第一是基于用户分布及成本的考虑;
2)第二是能为用户提供就近接入;
3)第三是能够让接入网关具备一定容灾能力。
大家可以设想下,如果没有三地部署,接入网关机房故障时,那么平台就瘫痪了。
随着平台业务规模的进一步扩大,日吞吐量达到10亿的量级,用户对于时效性、并发要求越来越高。而年的逻辑服务的系统架构已经无法业务高并发的需求或者需要更高的服务器成本才能满足高并发需求。
所以从平台功能、成本优化出发,在年对系统进行了重构,为用户提供更加丰富的产品功能及更稳定、更高性能的平台。
8、利用长连接能力给更多业务赋能
作为公司较大规模的长连接服务平台,团队积累了非常丰富的长连接经验。我们也一直在思考,如何让长连接能力为更多业务赋能。
我们平台服务端各个模块之间通过RPC调用,这是一种非常高效的开发模式,不用每个开发人员都去关心底层网络层数据包的。
我们设想一下,如果客户端也能通过RPC调用后台,这一定是非常棒的开发体验。
未来我们将会提供VRPC通信框架,用于解决客户端与后台通信及开发效率问题,为客户端与后台提供一致的开发体验,让更多的开发人员不再关心网络通信问题,专心开发业务逻辑。
作为一个吞吐量超过百亿的推送平台其稳定性、高性能、安全都非常重要,接下来和大家分享,我们在系统稳定性、高性能、安全方面的实践经验。
9、vivo推送平台的领域模型
从上图的领域模型可以看出,推送平台以通信服务作为核心能力,在核心能力的基础上我们又提供了,大数据服务以及运营系统,通过不同接口对外提供不同的功能、服务。
以通信服务为核心的推送平台,其稳定性和性能都会影响消息的时效性。
消息的时效性是指,消息从业务方发起用设备收到的耗时。
那么如何衡量消息的时效性呢?我们继续往下看。
10、如何实现消息时效性的监控与质量度量?
传统的消息时效性测量方法如上图左所示:发送端和接收端在两个设备上,在发送的时候取时间t1、在接收到消息的时候取时间t2,这两个时间相减得到消息的耗时。
但是这种方法并不严谨,为什么呢?因为这两个设备的时间基准,很有可能是不一致的。
我们采用的解决方案如上图右图所示:将发送端和接收端放在同一个设备上,这样就可以解决时间基准的问题。我们就是基于该方案,搭建了一套拨测系统,来主动监控消息送达耗时分布。
11、如何实现高性能、稳定的长连接网关?
过去10年讨论单机长连接性能时面对的是单机一万连接的问题(C10K问题),而作为一个上亿级设备同时在线的平台,我们要面对的是单机万连接的问题。
作为长连接网关,主要职责是维护与设备端的TCP连接及数据包转发。
对于长连接网关:我们应该尽可能使其轻量化。
我们从以下几方面进行了自上而下的重构优化:
1)架构设计;
2)编码;
3)操作系统配置;
4)硬件特性配置。
具体的实施方法,比如:
1)调整系统最大文件句柄数、单个进程最大的文件句柄数;
2)调整系统网卡软中断负载均衡或者开启网卡多队列、RPS/RFS;
3)调整TCP相关参数比如keepalive(需要根据宿主机的session时间进行调整)、关闭timewaitrecycles;
4)硬件上使用AES-NI指令加速数据的加解密。
经过我们优化之后,线上8C32GB的服务器可以稳定支持万的长连接。
另外一大难点在于连接保活:一条端到端的TCP连接,中间经过层层路由器、网关,而每个硬件的资源都是有限的,不可能将所有TCP连接状态都长期保存。
所以为了避免TCP资源,被中间路由器回收导致连接断开,我们需要定时发送心跳请求,来保持连接的活跃状态(为什么TCP有这样的问题?有兴趣可以读这两篇:《为什么说基于TCP的移动端IM仍然需要心跳保活?》、《彻底搞懂TCP协议层的KeepAlive保活机制》)。
心跳的发送频率多高才合适?发送太快了会引起功耗、流量问题,太慢了又起不到效果,所以为了减少不必要的心跳及提升连接稳定性,我们采用智能心跳,为不同网络环境采用差异性的频率。
有关长连接心跳机制的更详细资料,可以参阅:
《手把手教你用Netty实现网络通信程序的心跳机制、断线重连机制》
《一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等》
《移动端IM实践:实现Android版