1、引言
本文内容来自 vivo 互联网服务器团队李青鑫在“2021 vivo 开发者大会”现场的演讲内容整顿而成(现场演讲稿可从本文末附件中下载)。本文将要分享的是手机厂商 vivo 的零碎级推送平台在架构设计上的技术实际和总结。这也是目前为止首次由手机厂商分享的自建零碎级推送平台的技术细节,咱们也得以借此机会一窥厂商 ROOM 级推送通道的技术水准。
学习交换:
- 挪动端 IM 开发入门文章:《新手入门一篇就够:从零开发挪动端 IM》
- 开源 IM 框架源码:https://github.com/JackJiang2…(备用地址点此)
-
(本文已同步公布于:http://www.52im.net/thread-40…)
2、对于作者
李青鑫,vivo 互联网服务器团队架构师。
3、为什么须要音讯推送
音讯推送对于挪动端 APP 来说,是很常见的业务特色,比方新闻 APP 中的最新资讯、社交利用中的零碎告诉、IM 即时通讯利用的离线聊天音讯等等。
能够说,没有音讯推送能力,APP 就失去了实时触达的能力,对于一个利用来说,它对用户的“粘性”将大大降落。而对于用户来说,信息实时获取的能力也将大大降低,用户体验也将大幅降落。
4、音讯推送的技术阻碍
以咱们日常最常见的 IM 利用来说,离线音讯的推送是必备能力。但随着 Android 零碎的一直降级,离线推送曾经不单单是一个后盾服务加长连贯那么天经地义了。
对于晚期的 Android 零碎来说,想要实现 IM 的离线音讯推送并不艰难,搞个后盾服务再加上 socket 长连贯就算是齐活了。但随着 Android 零碎的降级,针对后盾过程和网络服务限度一直加码,为了持续实现离线音讯的推送,开发者们不得不跟零碎斗志斗勇,搞出了各种保活黑科技,比方:Android4.0 之后的双过程守护、Android6.0 及之后的防杀复活术、以及倒退到起初的腾讯 TIM 过程永生技术,一时间群魔乱舞、无比风骚(有趣味的同学,能够读读《Android 过程永生技术终极揭秘:过程被杀底层原理、APP 应答被杀技巧》这篇针对所有保活黑科技的总结性文章)。
随着 Andriod 9.0 的到来,根本从零碎上堵死了各种保活黑科技的生路(详见《Android P 正式版行将到来:后盾利用保活、音讯推送的真正噩梦》),各 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、业务需要驱动架构降级
对于零碎的技术架构来说,它是动静的,不同阶段都可能会发生变化。而推动架构进行演进的推力,次要来自于业务需要,一起来回顾,平台的业务倒退历程。
自 2015 年立项以来,随着业务量增长,一直为零碎增加性能个性,丰盛整个零碎的能力使其满足不同的业务场景需要。比方反对内容齐全审核、反对 IM、反对 IoT、反对 WebSocket 通信等。从图上能够看到,业务量简直每年都有几十亿的增长,一直攀高,给零碎带来了挑战,原有的零碎架构存在的问题,也逐步浮出水面,比方提早、性能瓶颈。架构服务于业务,2018 年之前咱们平台所有服务都放在云上,然而依赖的其余外部业务部署在自建机房。
随着业务量增长与自建机房的数据传输,曾经呈现了提早的问题,并且在逐步好转,不利于咱们平台性能的拓展。所以在 2018 年下半年,咱们对部署架构进行调整:将所有外围逻辑模块都迁徙到自建机房,架构优化之后,数据提早问题失去彻底解决,同时也为架构进一步演进奠定了根底。从下面的图中能够看到咱们接入网关也进行优化三地部署。
为什么要进行三地部署而不是更多区域部署呢?次要基于以下三点思考:
1)第一是基于用户散布及老本的思考;
2)第二是能为用户提供就近接入;
3)第三是可能让接入网关具备肯定容灾能力。
大家能够构想下,如果没有三地部署,接入网关机房故障时,那么平台就瘫痪了。随着平台业务规模的进一步扩充,日吞吐量达到 10 亿的量级,用户对于时效性、并发要求越来越高。而 2018 年的逻辑服务的零碎架构曾经无奈业务高并发的需要或者须要更高的服务器老本能力满足高并发需要。所以从平台性能、老本优化登程,在 2019 年对系统进行了重构,为用户提供更加丰盛的产品性能及更稳固、更高性能的平台。
8、利用长连贯能力给更多业务赋能
作为公司较大规模的长连贯服务平台,团队积攒了十分丰盛的长连贯教训。咱们也始终在思考,如何让长连贯能力为更多业务赋能。咱们平台服务端各个模块之间通过 RPC 调用,这是一种十分高效的开发模式,不必每个开发人员都去关怀底层网络层数据包的。
咱们构想一下,如果客户端也能通过 RPC 调用后盾,这肯定是十分棒的开发体验。将来咱们将会提供 VRPC 通信框架,用于解决客户端与后盾通信及开发效率问题,为客户端与后盾提供统一的开发体验,让更多的开发人员不再关怀网络通信问题,分心开发业务逻辑。作为一个吞吐量超过百亿的推送平台其稳定性、高性能、平安都十分重要,接下来和大家分享,咱们在零碎稳定性、高性能、平安方面的实践经验。
9、vivo 推送平台的畛域模型
从上图的畛域模型能够看出,推送平台以通信服务作为外围能力,在外围能力的根底上咱们又提供了,大数据服务以及经营零碎,通过不同接口对外提供不同的性能、服务。以通信服务为外围的推送平台,其稳定性和性能都会影响音讯的时效性。
音讯的时效性是指,音讯从业务方发动用设施收到的耗时。那么如何掂量音讯的时效性呢?咱们持续往下看。
10、如何实现音讯时效性的监控与品质度量?
传统的音讯时效性测量方法如上图左所示:发送端和接收端在两个设施上,在发送的时候取工夫 t1、在接管到音讯的时候取工夫 t2,这两个工夫相减失去音讯的耗时。然而这种办法并不谨严,为什么呢?因为这两个设施的工夫基准,很有可能是不统一的。
咱们采纳的解决方案如上图右图所示:将发送端和接收端放在同一个设施上,这样就能够解决工夫基准的问题。咱们就是基于该计划,搭建了一套拨测系统,来被动监控音讯送达耗时散布。
11、如何实现高性能、稳固的长连贯网关?
过来 10 年探讨单机长连贯性能时面对的是单机一万连贯的问题(C10K 问题),而作为一个上亿级设施同时在线的平台,咱们要面对的是单机 100 万连贯的问题。
作为长连贯网关,主要职责是保护与设施端的 TCP 连贯及数据包转发。对于长连贯网关:咱们应该尽可能使其轻量化。
咱们从以下几方面进行了自上而下的重构优化:
1)架构设计;
2)编码;
3)操作系统配置;
4)硬件个性配置。
具体的施行办法,比方:
1)调整零碎最大文件句柄数、单个过程最大的文件句柄数;
2)调整零碎网卡软中断负载平衡或者开启网卡多队列、RPS/RFS;
3)调整 TCP 相干参数比方 keepalive(须要依据宿主机的 session 工夫进行调整)、敞开 timewait recycles;
4)硬件上应用 AES-NI 指令减速数据的加解密。
通过咱们优化之后,线上 8C32GB 的服务器能够稳固反对 170 万的长连贯。
另外一大难点在于连贯保活:一条端到端的 TCP 连贯,两头通过层层路由器、网关,而每个硬件的资源都是无限的,不可能将所有 TCP 连贯状态都长期保留。所以为了防止 TCP 资源,被两头路由器回收导致连贯断开,咱们须要定时发送心跳申请,来放弃连贯的沉闷状态(为什么 TCP 有这样的问题?有趣味能够读这两篇:《为什么说基于 TCP 的挪动端 IM 依然须要心跳保活?》、《彻底搞懂 TCP 协定层的 KeepAlive 保活机制》)。
心跳的发送频率多高才适合?发送太快了会引起功耗、流量问题,太慢了又起不到成果,所以为了缩小不必要的心跳及晋升连贯稳定性,咱们采纳智能心跳,为不同网络环境采纳差异性的频率。
无关长连贯心跳机制的更详细资料,能够参阅:
《手把手教你用 Netty 实现网络通信程序的心跳机制、断线重连机制》
《一文读懂即时通讯利用中的网络心跳包机制:作用、原理、实现思路等》
《挪动端 IM 实际:实现 Android 版微信的智能心跳机制》
《挪动端 IM 实际:WhatsApp、Line、微信的心跳策略剖析》
《一种 Android 端 IM 智能心跳算法的设计与实现探讨(含样例代码)》
《正确理解 IM 长连贯、心跳及重连机制,并入手实现》
《万字长文:手把手教你实现一套高效的 IM 长连贯自适应心跳保活机制》
《Web 端即时通讯实际干货:如何让你的 WebSocket 断网重连更疾速?》
12、如何实现亿级设施的负载平衡?
咱们平台超过亿级设施同时在线,各个设施连贯长连贯网关时是通过流量调度零碎进行负载平衡的。当客户端申请获取 IP 时,流量调度零碎会下发多个就近接入网关 IP:
那么调度零碎是如何确保下发的 ip 是可用的呢?大家能够简略思考下。
对于我来来说,咱们采纳四种策略:
1)就近接入;
2)公网探测;
3)机器负载;
4)接口成功率。
到底采纳这几种策略呢?大家能够想下,这两个问题:
1)内网失常,公网就肯定能联通吗?
2)连接数少服务器,就肯定是可用的吗?
答案是否定的,因为长连贯网关与流量调度零碎是通过内网进行心跳保活的,所以在流量调度零碎上看到的长连贯网关是失常的,然而很有可能长连贯网关公网连贯是异样的比方没有开明公网权限等。
所以咱们须要联合多种策略,来评估节点的可用性,保障系统的负载平衡、为零碎稳定性提供保障。
13、如何满足高并发需要?
有这么一个场景:以每秒 1000 的推送速度,将一条新闻发送给几亿用户,那么有的用户可能是几天后才收到这条音讯,这就十分影响用户体验,所以高并发对音讯的时效性来说是十分重要的。
从上图的推送流程来看:会不会感觉 TiDB 会成为推送的性能瓶颈?其实不会:初步看可能会感觉它们作为核心存储,但因为咱们采纳分布式缓存,将核心存储的数据,依据肯定的策略缓存到各个业务节点,充分利用服务器资源,晋升零碎性能、吞吐量。咱们线上的分布式缓存命中率 99.9% 为核心存储挡住了绝大部分申请,即便 TiDB 短时间故障,对咱们影响也比拟小。
14、如何保障系统稳定性?
14.1 概述作为推送平台,平台的流量次要分为内部调用及外部上下游之间的调用。它们大幅稳定都会影响零碎的稳定性,所以须要进行限流、控速,保障系统稳固运行。
14.2 推送网关限流
推送网关作为流量入口,其稳定性十分重要。要让推送网关稳固运行,咱们首先要解决流量平衡的问题即防止流量歪斜的问题。因为流量歪斜之后,很有可能会引起雪崩的状况。咱们是采纳轮询的机制,进行流量的负载平衡,来防止流量歪斜问题。然而这里有两个前提条件:1)所有推送网关节点,服务器配置要保持一致,否则很有可能会因为某个解决能力有余导致过载问题;2)应管制流入咱们零碎的并发量,防止流量洪峰穿透推送网关导致后端服务过载。咱们采纳的是令牌桶算法,管制每个推送网关投放速度,进而可能对上游节点起到爱护作用。那么令牌数量设置多少才适合呢?设置低了,上游节点资源不能充分利用;设置太高了,上游节点有可能扛不住。
咱们能够采纳被动 + 被动的动静调整的策略:
1)当流量超过上游集群解决能力时,告诉上游进行限速;
2)当调用上游接口超时,达到肯定比例是进行限流。
14.3 零碎外部限速:标签推送平滑下发
既然推送网关曾经限流了,为什么外部节点之间还要限速?
这个是因为咱们平台的业务特点决定的,平台反对全量、标签推送,要防止性能较好的模块,把上游节点资源耗尽的状况。标签推送模块(提供全量、标签推送)就是一个性能较高的服务,为了防止它对上游造成影响。咱们基于 Redis 和令牌桶算法实现了平滑推送的性能,管制每个标签工作的推送速度,来爱护上游节点。
另外:平台反对利用创立多个标签推送,它们的推送速度会叠加,所以仅管制单个标签工作的平滑推送是不够的。须要在推送下发模块对利用粒度进行限速,防止推送过快对业务后盾造成压力。
14.4 零碎外部限速:音讯下发时限速发送
为了实现利用级别的限速,咱们采纳 Redis 实现分布式漏桶限流的计划,具体计划如上图所示。这里咱们为什么采纳的是 clientId(设施惟一标识),而不是应用利用 ID 来做一致性 hash?次要是为了负载平衡。自从实现了这个性能之后,业务方再也不必放心推送太快,造成本人服务器压力大的问题。
那么被限速的音讯会被丢掉吗?当然不会,咱们会将这些音讯存储到本地缓存、并且打散存储到 Redis,之所以须要打散存储次要是为了防止后续呈现存储热点问题。
14.5 熔断降级
推送平台,一些突发事件、热点新闻会给零碎带来较大的突发流量。咱们应该如何应答突发流量呢?
如上图左所示:传统的架构上为了防止突发流量对系统的冲击,冗余部署大量机器,老本高、资源节约重大。在面临突发流量时,无奈及时扩容,导致推送成功率升高。咱们是怎么做的呢?咱们采纳减少缓冲通道,应用音讯队列和容器的解决方案(这种计划零碎改变小)。当无突发流量时以较小量机器部署,当遇到突发流量时咱们也不须要人工染指,它会依据零碎负载主动扩缩容。
15、基于 Karate 的自动化测试
零碎在日常开发中大家为了疾速开发需要,往往漠视了接口的边界测试,这将会给线上服务造成很大的品质危险。另外,不晓得大家有没有留神到,团队中不同角色沟通时应用的不同媒介比方应用 word、excel、xmind 等,会导致沟通的信息呈现不同水平折损。所以为了改善以上问题,咱们开发了一个自动化测试平台,用于晋升测试效率与接口用例覆盖率,咱们采纳畛域对立的语言缩小团队中不同角色沟通信息折损。另外还能够对测试用例对立集中管理,不便迭代保护。
16、内容平安
作为推送平台,当然要为内容平安把好关,咱们提供了内容审计的能力。审计办法采纳主动审核为主、人工审核为辅机制来晋升审核效率。同时联合基于影响面及利用分级的策略进行内容审计。从下图中能够看到业务申请通过接入网关转发给内容审零碎进行第一层本地规定的内容审计,如果没有命中本地规定则调用咱们谛听零碎进行内容反垃圾审计。
17、将来布局
后面咱们次要介绍了推送平台这几年的架构演进及演进过程中的零碎稳定性、高性能、平安等方面的技术实际,接下来介绍将来的重点工作。
为了提供更易用、更稳固、更平安的推送,将来将在以下方面继续投入建设:
1)在单模块数据一致性的根底上,实现全零碎数据一致性;
2)将持续欠缺各零碎的熔断降级能力;
3)平台的易用性方面继续优化,提供更加便捷的平台服务;
4)建设异样流量辨认的能力。
18、演讲稿附件下载
本文内容对应的演讲原稿附件下载:vivo 推送平台架构演进 (52im.net).pdf (1.93 MB) 演讲原稿内容概览:
19、参考资料
[1] Android6.0 以下的双过程守护保活实际
[2] Android6.0 及以上的保活实际(过程防杀篇)》
[3] 为何基于 TCP 协定的挪动端 IM 依然须要心跳保活机制?
[4] Android 版微信后盾保活实战分享(过程保活篇)
[5] 实现 Android 版微信的智能心跳机制
[6] Android P 正式版行将到来:后盾利用保活、音讯推送的真正噩梦
[7] 融云安卓端 IM 产品的网络链路保活技术实际
[8] 正确理解 IM 长连贯的心跳及重连机制,并入手实现
[9] 史上最强 Android 保活思路:深刻分析腾讯 TIM 的过程永生技术
[10] Android 过程永生技术终极揭秘:过程被杀底层原理、APP 反抗被杀技巧
[11] Web 端即时通讯实际干货:如何让你的 WebSocket 断网重连更疾速?
(本文已同步公布于:http://www.52im.net/thread-40…)