网易云信IM云之安卓微观搏杀中的“存活绝技”

1902℃

根据Talkingdata最新的2016年9月监测数据,中国现有移动智能终端41亿多部,其中70%是安卓设备。而早在2012年的时候,全球安卓APP应用商店里的APP数量就已超过了100万个,如今规模又进一步扩大到150万个左右。这么多的安卓APP在拼抢接近30亿部安卓终端,APP之间的微观博杀已经到了近乎残酷的地步。

除了拼抢市场、扩大用户数量外,如何提升用户的日活跃度和粘性,也是安卓APP的存活之道。对于移动APP来说,即时消息IM功能正变得越来越重要:推送消息能刷出APP的存在感;IM能强化人与人之间的连接,在社交类产品中的用户与用户间沟通可以产生出更好的粘性。因此,在提升用户日活和粘性方面,即时消息IM的稳定性与可靠性非常重要。

不了解不知道,原来安卓后台无时无刻不上演各APP之间拼抢系统和网络资源、用各种方法绞杀其它APP的即时消息,从而提升自己存活机会的微观大搏杀!究竟这个大搏杀激烈到什么程度,在这个大搏杀中的存活绝招有哪些?

微观搏杀之“内存杀手”

对于iOS来说,有 APNS服务做消息推送,系统相当稳定。对安卓本身来说,在国外也有Google的GCM服务可用,但在国内却无法使用Google的服务。对于IM来说,当APP应用退到安卓后台系统后,还必须能够收到新消息提醒的。没有GCM,怎么办?

在最开始的时候,唯一能做的就是保持APP的后台运行了。但其实手机等设备的内存是拒绝后台运行APP的,后台运行了太多的APP会导致应用卡顿、不断耗电、系统性能下降等问题。因此,安卓系统对于后台运行的APP也不会放任自流。但后台运行,却是保持IM推送的几乎唯一也是最主要的途径。

APP想要在后台保持运行,需要面对不少“杀手”。第一大杀手就是安卓的Low Memory Killer(LMK,“低内存杀手”)机制。因为手机的内存毕竟有限,当后台运行的进程越来越多,内存剩余量也就随之减少。当有一个新的APP想要启动,而如果此时内存不够了,LMK机制就会启动,从正在运行的APP进程中挑选一个清理掉,释放出空间。

LMK有两个尺度去评判要“杀掉”哪个在后台运行的APP进程。一个是APP进程优先级,优先级越低,被清理的可能性越大;另一个是内存占用,占的内存越多,被清理的权重自然也越大。

微观搏杀之“用户的剑”

除了系统LMK能够杀掉后台运行的APP进程外,用户也一样可以杀死进程。

用户杀掉进程的方式有两种,一种是在最近任务列表中将APP划掉,这种方式和系统杀掉进程效果相同。另外一种就是通过Force Stop“强制停止”,这种方式比系统清理更加彻底。不但正在运行的APP进程会被清理,APP在重启列表中的待重启服务、注册的各种闹钟、事件监听组件等都会被移除,除非用户再主动点击或者系统重启等外力,APP没法再自己重新“爬”起来了。

此外,国内MIUI一类的ROM上,用户从最近任务列表中将APP移除,效果竟然也是Force Stop“强制停止”。正常来说,如果是用户主动操作,APP本身也不应该再重启了。但有些时候这并非用户本意,而且对于IM功能来说,一定要保障消息推送,否则会被不明就里的群众误认为软件本身有问题。

微观生存之“全家桶”

在目前国内的Android生态环境中,无论采用什么方式,想要一直在后台保持APP的运行越来越难了。

为了“生存”,当一个APP进程起来后,就去扫描已安装的应用列表,看看有没有自己的“同源兄弟姐妹”,比如集成了同一个SDK(开发工具包)的APP等,如果有的话就把这些APP“抱团”起来,互相保活、互相唤醒。这就是现在比较出名的“全家桶”方案。

虽说这种方法确实能够带来较高的后台存活率,特别是那些大厂和应用广泛的SDK。如果有后台推送的必要性,而且不会对用户体验造成太大伤害时,此方式还可以使用。但如果只是为了推广告,则会对用户造成伤害,反过来也可能会导致用户直接卸载APP。

因为“全家桶”实在是太令人讨厌,现在各种手机管理软件都会对这种唤醒方式做限制,特别是在root过的机器上,可以做到完全切断这些唤醒路径。同时,很多手机的ROM(只读存储器,带有系统重启软件包)也会自带管理软件,限制后台运行和后台唤醒,以便给设备换取更长的续航。

微观生存之“共享心跳”

传统上,每个IM客户端都会各自维护一条与服务器的长连接,各自的消息和信令都在这条长连接上传递,每个APP也独自发送“心跳”信息、断线重连等事情。

所谓“心跳”机制,最早用于服务器的安全备份,为了防止服务器死机而在服务器之间周期性传送简短的“心跳”信息,一旦收不到对方的“心跳”信息,服务器可以接管对方的业务,避免业务的停滞。到了手机上,无论是安卓的原生应用,还是QQ、微博和微信,都采用了心跳机制,也就是APP终端定时向应用服务器发送简短的信息。

各自独立“心跳”的话,不同APP之间完全隔离、不会互相影响。但缺点也非常明显,首先是做了很多重复的工作,造成了流量和电量的无谓消耗,第二是要保证所有的进程都能在后台运行确实很艰难。

所谓“共享连接”,就是从众多APP里面选出一个当前正在运行的,或者是被杀概率最低的APP作为总代理,由这个代理和服务器建立连接,手机上的所有其他APP都通过这个代理中转与服务器通信。所有APP的消息都经过代理中转,代理到服务器的连接是加密的,但到了代理这里理论上可以看到其它所有APP的来往消息。因此,这种共享长连接的方式并不适用于IM。

存活绝技之“独行侠”与“影子武士”

周江华是网易资深安卓开发工程师,先后主导参与了易信、网易云信、网易七鱼的客户端开发工作,拥有非常丰富的功能开发以及代码优化经验。2016年9月23日,MDCC 2016中国移动开发者大会上,周江华介绍了网易云信IM在应对弱网环境、移动端硬件限制以及Android复杂的生态现状时的探索与心得。

周江华介绍说,虽说APP终究免不了一死,但通过对照LMK的评判准则,还是可以降低APP被清理的概率。第一个就是降低APP进程的内存占用。如果采用单进程的模式,由于进程中包含了UI、Webview、图片缓存等内容,内存占用必然会居高不下。因此,IM软件一般都会采用双进程甚至多进程的策略,将push进程独立出来——在push进程里只处理网络连接和push业务,不参与任何其他业务逻辑,更不包含任何UI。这有些“独行侠”的意思。

网易云信Android SDK架构

网易云信Android SDK架构

上图为网易云信Android SDK架构,按照分层的结构模式设计。最底下为push层,就是作为一个独立进程运行,只负责处理网络长连接的相关工作,比如安全加密、心跳、鉴权、封包、解包等工作,所有业务逻辑都交给UI进程的服务模块去做。再看一下云信demo的进程内存占用情况,push进程的内存占用只有10M左右。因此,当处于后台时,push进程被清理概率比UI主进程低很多。

降低被清理概率的第二个手段是提升进程优先级。实际上,安卓的前台服务设计上有一个漏洞,通过两个服务的配合就能创建一个隐形的前台服务。也就是启动两个服务进程,每一个都赋予了同样的进程ID,但在常驻通知栏中只有一个相应的进程ID,这样一旦系统关掉一个进程ID的时候,尽管“杀掉”了一个前台服务和相应的常驻通知栏进程,但还有一个隐形的服务仍在存在而且不会受到任何影响。这种“影子武士”的好处是,用户不会有任何感知,但仍然能获得“幕后”的消息保护。

存活绝技之“龙威镖局”

前面提到了共享长连接的方式并不适合IM,但适当的优化仍然可以保障IM,这就是脱敏共享连接的方式:安全长连接加推送连接模式。

所谓“安全长连接加推送连接模式”就是每个APP在使用和真正传递数据时,仍然独立使用自己的安全长连接,而当APP退到后台一段时间后则断开长连接,然后开启一个推送代理,选择其中一个与云信的推送服务器建立连接。之后当APP有新消息时,就通过这个推送连接传递。这种情况下,APP可以控制发出的推送消息的安全级别。这种代理机制相当于给APP的消息传递找到了一个“镖局”,既保证了消息的安全性,又保证了传送的效率。

采用代理连接的方式,当推送消息到达后台,如果是代理APP自己的消息就直接传递给APP即可,如果是其他APP消息,就发出一条通知栏提醒,等用户点击通知栏提醒后,才会把目标APP唤醒。之所以通过通知栏提醒而不是直接唤醒APP,一方面是因为直接唤醒可能会失败,另一方面是如果唤醒而不使用就会导致无谓的电量消耗。

此外,现在国内的ROM中,华为和小米的操作系统自带推送系统且开放给了第三方APP。在华为和小米的系统中,使用系统自带的推送通道会更稳定、也更节省资源。因此在MIUI上,从长连接到推送通道的切换流程仍然和前述一样,只是把消息转发到MIUI的推送服务器,然后再传递给云信的APP,华为的推送系统流程也是一样。

不过华为和MIUI在推送的实现上略有区别,MIUI的通知栏提醒是在系统的推送代理里完成,而华为却是将提醒通知交给APP去完成。另外,它们系统通知栏提醒的管理接口也有区别,在APP没有被禁用的情况下,两者都可以收到推送,而如果APP已经被禁用了,MIUI的通知栏提醒方式还可以将推送送达,而其它的推送方式则不能送达了。

突破弱网环境的三大限制

相对于PC的网络环境,周江华总结手机网络有3个特点:第一个是慢,尤其是2G、3G网络,慢的令人发指;其次是断,手机跟着人不停的移动,网络也不停的在切换,从wifi到移动网络、从一个基站到另一个基站、从有信号到没信号,都可能导致网络中断;第三是贵,只要看中国移动每天净赚一个亿就知道了。

在网易云信整个通信系统中,有三种类型的连接,即TCP、UDP和HTTP。三种类型的协议对应了不同的业务应用:TCP主要是用户长连接,也就是普通IM消息和信令的传输;UDP用于传输实时音视频数据流;而HTTP则主要用在音频、图片等文件的上传下载上。

对于长连接,可以采用开源协议,有成熟的解决方案、扩展性好、可读性好,甚至还可以和其它系统互联互通,但问题是协议文本普遍比较臃肿、冗余字段很多,在昂贵的移动网络里自然就成本比较贵。网易云信采用的是私有的二进制协议,以“0/1”方式表达的二进制协议完全失去了可读性,但却带来极高的表达效率,相对于文本协议可以节省非常多的数据流量。此外,在判断LBS地址、发出登录请求、建立安全连接的协议握手等,可以通过并行和增量操作的方式,把登录时间降为原来的1/2到1/3、登录的流量消耗也可以节省30%左右。

对于用于传输实时音视频数据流的UDP协议,为了提高弱网下的实时音视频的通话效果,需要使用相关方案来做QoS质量保障;同时网络层需要实时探测网络状态,作为底层调整QoS策略的依据;还要回调上层,动态调整音视频的码率,做到音视频码率自适应。通过上面的QoS保障,实际测试在20%的随机丢包弱网环境下,音视频通话还能够正常进行。网易云信针对音频和视频,还采取了一系列的优化方法,以保证弱网条件下音频和视频的质量。

对于图片和语音文件,网易云信并没有通过长连接收发,而是通过HTTP上传下载。为了提高HTTP分片上传过程中网络的利用效率,网易云信也采取了有效的优化方法,把图片文件上传时间减少20%至30%,以及保证常规语音消息的正常发送和接收。

综上所述:一直以来,提升消息推送达到率和到达速度、优化网络利用效率、节省系统资源等,都是安卓系统开发的核心和基础,而网易云信IM SDK在不影响用户体验前提下,可实现后台保活、改善长连接加推送组合以及优化弱网环境大数据传输。

网易云信是如何成为“技术侠”的?

网易在即时通讯领域已经有十多年的积累,从网易邮箱到网易泡泡再到易信,网易有多款用户过亿的移动端产品,这让网易云信拥有了丰富的移动端解决方案优化经验。

在2014年底,网易重新组建了网易云信团队,请来了一流的产品团队加入,并增加了商务与技术支持,以便全方位的为客户提供更加便捷和贴身的服务。网易云信目前已成功发送超过1000亿条消息,每日上亿条消息100%到达。自2015年10月推出,网易云信已经累积了10万+开发者,连接了2.4亿用户。

周江华介绍,网易云信提供专业的“T服务”,一站式快速响应和解决开发者和用户的问题。该服务体系包含网易云信技术顾问服务体系、客户顾问服务体系、用户信任服务体系三大块。网易云信技术顾问团队是业内唯一一家提供1对1、7×24小时即时响应技术支持服务的团队,团队成员均来自一线互联网公司。

在用户信任方面,网易云信提供了故障赔偿、邮件短信双重预警、1月信用额度等保障服务。网易云信特别成立了网易云信用户信任中心,把产品升级、专利技术、第三方机构云认证等方面的信息同步公示给用户,其中包括CSA STAR Certification、ISO27001信息安全管理体系国际认证在内的多项云安全类认证服务及奖项,并确保用户可享受到云信的56项专利技术。

宝宝树是目前国内最大的母婴垂直网站,旗下的“宝宝树孕育”、“小时光”、“美囤妈妈”三款APP均使用了网易云信的聊天室+直播技术。在与竞争对手的PK中,网易云信凭借更小的包、不占空间、技术支持响应快、聊天室性能好、稳定无异常等优势,成功被宝宝树选中。

学吧课堂是一个主打 K12 领域的游戏化自适应学习的在线平台,其IM使用场景主要在排行榜,可选择排行高的学生,添加好友后进行私聊。同时,学吧课堂的教学白板、实时音频、实时视频也是用了网易云信的技术。

总结下来,在安卓的微观世界里,网易已经拼杀了很多年。如今这些累积的IM“存活绝技”都通过网易云信向外输出,这无疑是开发者的福音。正如网易创始人的丁磊在9月20日“网易云”整体发布会上所说,“网易云产品的推出,就是要解放全中国千千万万的程序员,让他们过上钱多、事少、离家近的幸福生活”。