淘宝APP消息推送模型

为什么到了2020年,“统一推送联盟”依旧无法起显著作用? - 知乎 https://www.zhihu.com/question/370632447

https://mp.weixin.qq.com/s/ZL1v2Tyl3OC0V8ZrSgax2A

淘宝APP消息推送模型

絮叨

之前讨论过TCP连接相关的问题:

手机上的APP是如何与服务器通信的

      对于国民生态级APP,像淘宝天猫支付宝等,支撑大量扫码、AR、视频直播和实时聊天等业务,背后的服务器集群数十万计(算上国外POP点),必须要考虑网络质量的稳定性和消息到达的时效性。移动通信模块涉及的终端技术点很多,本文先从长连接讲起,将大型APP的通信原理和通信质量保障一点点理清。

       一般APP主进程退出之后还会留一个push进程来接收服务端的推送消息,在安卓机上用过QQ微信或者支付宝的应该都有印象,明明把APP进程杀掉了,系统推送的消息还是能收到。一般大型APP都是自建http/tcp长连通道,小型app可以直接使用阿里云定制的推送功能。像即时聊天类APP如微信的消息收发非常及时,背后功劳就是这套长连接系统。不得不说,微信的消息推送质量基本高达98%,略高于阿里系的淘宝和支付宝。

长连接

之前面试阿里的时候,面试官问过一个问题:TCP的keepalive和http的keep-alive长连接有什么区别?两者的侧重点不太相同。客户端与服务端通信流程为:客户端dns请求获取服务端ip地址,之后经过tcp三次握手建立连接,tls握手交换对称密钥(这里如果中间证书过大的话还要中断握手先下载证书),然后才是http的数据通信。如果是短连接,数据传输完后服务端就会主动关闭连接,下次再发数据时又要经过上一次繁杂的握手流程。而http1.1里面的keep-alive字段就是为了告知双方继续保持这条连接,免去握手流程。而TCP的keepalive机制是启动一个定时器,如果双方两小时没有任何数据收发传输(两人都不说话),那么服务端会向客户端发送一个一字节探测报文,如果客户端没有回应,连续10次探测之后发送reset报文断开这条连接。

通知推送

安卓和iOS手机都能收到APP的推送消息,但是实现机制不一样。iOS是依靠系统内部的常驻推送进程与苹果自己的APNS服务器通信,转发淘宝服务器发出的通知。

而安卓不一样,是各家自己单独维护或者租用一条推送链路。安卓版APP一般除了执行数据运算的主进程之外,还会维持一条push进程用于长连接,主要是发送心跳包和接收自家服务推送,这也是安卓机内存越来越不够用的原因之一。

      杀进程,一般是清除APP的主进程,push进程因为占用内存相对比较小,被系统杀掉的可能性不太高,在后台继续运行;有些软件在push进程被杀掉后还可以通过AlarmReceiver及时拉起进程。       

        目前几大主流手机厂家华米OV联合BAT和google推出了统一推送联盟,向iOS看齐,各大APP统一使用一条推送通道,好处主要有以下几点:

1、APP不需要特意保活,减少了手机内存占用和耗电量;

2、可以对推送消息统一进行权限管理和控制,减少垃圾消息;

3、减少APP厂商开发适配难度(想象一下用C++开发完Android版本马上用object-c开发iOS版本的蛋疼场景)

阿里系APP借鉴http协议自己实现了一套长连接机制,主要用于应对大量网络请求及信令包的传输,减少耗时,其次服务端可以主动使用push通道推送数据到客户端。这种情况如果采用客户端轮询机制实现的话会消耗服务器大量带宽,也会造成运营商信令风暴。长连接大体部署如下图:

注1:由于运营商NAT表老化,基本二十分钟(中国电信保活时间最长,为20分钟)后NAT表就会更新,这个时候服务端已经联系不上客户端了。后面会讲到客户端发送心跳包保活连接,主要也是这个原因。

注2:淘宝为什么不把服务端的IP直接写到程序里,而是要通过dns花费1rtt耗时通过运营商请求呢?主要是为了服务器集群容灾,其次是就近接入。

连接保活

为了解决上面说到的NAT超时导致连接断开的问题,通常的操作是客户端以略小于NAT超时的间隔发送心跳包。但是采用固定心跳方法,会增加手机功耗,消耗大量信令资源,而且不同WiFi信号下NAT超时通常较长如20min,如果继续采用5min心跳一次则浪费资源。因此淘宝采用智能心跳策略,动态逐渐递增探测到NAT时间后,探测思路借鉴了TCP探测拥塞窗口的思路。当APP处于后台时,为减少电量消耗及频繁唤醒系统,在前台熄屏或者刚进入后台时递增探测最长心跳时间,在后台稳定态(一般为10min)时采用最大心跳作为固定值。

此外,Android系统为减少系统频繁唤醒,提供了定时器对齐机制,即把一定时间段内的多个定时器中断唤醒合并成一个中断,这个思路也被很多嵌入式操作系统如freertos采纳,作为一个低功耗卖点。

假连接现象

当然长连接也不是一直保持着,移动网络跟有线网络相比环境复杂太多,移动通信需要考虑的点也很多,下面几种情况就会出现tcp假连接现象,也就是本地的socket资源还在,但是网络已经无法使用了。

1、切网

在电梯、地下室等弱网情况下,从有WiFi的地方走到4G网络覆盖的区域,虽然WiFi已经断开,但是手机进程里之前WiFi的信息还未清除,如果采用原来的IP通信肯定会失败。

2、后台清理进程

如果push进程被切入后台,那么安卓系统会在内存不足的情况下采用LRU算法清掉最久未使用的进程,push进程随时可能被杀掉。

3、NAT表老化

上文已经说明。

4、DHCP租期到期

        Android系统在处理dhcp到期续约时在某些机型上会出现bug,这个时候本地IP地址无效,只能重新建立tcp连接。

周末探讨一下VPN对APP无线网络性能的影响。

为什么到了2020年,“统一推送联盟”依旧无法起显著作用? - 知乎 https://www.zhihu.com/question/370632447

原文地址:https://www.cnblogs.com/rsapaper/p/13677610.html