IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Android 架构之长连接技术,直面秋招 -> 正文阅读

[网络协议]Android 架构之长连接技术,直面秋招

上一篇文章《Android 架构之网络框架(上)》中,我们谈过了网络框架OkHttp、网络加速方案如HttpDNS、数据压缩与序列化等技术点。本文我们结合腾讯Mars框架美团Shark体系等业内主流长连接方案,谈一谈长连接技术的各个方面。

本文会包括下面的技术点:

  • 长连接与Http短连接、Keep-Alive傻傻分不清
  • 你为什么需要长连接
  • 长连接何时会断开
  • 如何建立稳定长连接
  • Mars智能心跳机制
  • 长连接数据协议及加密
  • 长连接通道建设及容灾

除了大家常用的Http短连接,大型App几乎都会搭建一套完整的TCP长连接网络通道。我们先来看下美团Shark长连接的线上数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q74YIrIh-1630997908377)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1c4482042?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ajhaWScS-1630997908379)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1c1e31f3c?imageView2/0/w/1280/h/960/ignore-error/1)]

图片来源 《美团点评移动网络优化实践

上面两张图片对比了长/短连接的成功率和网络延时数据,这两个是网络模块最重要的衡量指标。可以看出,无论是成功率,还是网络延时,长连接都明显优于短连接。

另外,大家都知道微信的消息收发非常即时,这便归功于背后稳定高可用的长连接系统。实际上,微信除了消息收发,其他的小数据通信都是通过长连接来实现的。

下面我们来讲解一些长连接的一些核心技术点。

I. 长连接与Http短连接、Keep-Alive傻傻分不清

为防止大家对于长连接和短连接混淆,这里先简单说明下几点区别。

长连接 vs Http短连接

这两者分别对应的是TCP协议层长连接短连接

大家都知道,TCP会通过三次握手,建立与服务端的连接,然后传递数据,只不过短连接在数据传输完后,会主动关闭连接,而长连接会继续保持这条连接,后续的数据读写继续使用这条连接。

长连接 vs Http的Keep-Alive

上一篇文章中提到了连接复用,通过Http1.1的Keep Alive字段,我们可以让一条Http连接保持不被立即关闭。有些同学这时就疑惑了,是不是长连接就是Keep Alive呢?

其实不是的。长连接我们也叫TCP长连接,它是架设在TCP协议上的,而上面说的Keep Alive是Http协议的内容,连协议都不同,两者自然不是一个东西。

开启了Keep Alive是Http连接,我们也称之为持久连接,和长连接并不同。感兴趣可参考此文:《TCP 进阶》

TCP的Keep-Alive vs Http的Keep-Alive

提到Keep Alive,有些同学就会问了,TCP协议里也有一个Keep Alive,它和Http协议里的Keep Alive有什么区别吗?

二者的用处并不同。Http协议在完成一个请求后,服务器会自动关闭连接。这时,可以在请求里带上一个Keep Alive给服务器,告诉服务器不要立即关闭连接,我还想继续复用这条连接;而对TCP协议层而言,是不会自动断开的,但这也带来了一个问题,万一由于某些外部原因导致连接断开,那我如何知道连接已失效呢?TCP会在2个小时间隔后,自动发送一个Keep Alive数据包给服务端,探测一下服务器是否还在响应。它的功能类似心跳包,只是间隔太长,不适合做真正的心跳包。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dcaeytdp-1630997908380)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1c296b8e5?imageView2/0/w/1280/h/960/ignore-error/1)]

II. 你为什么需要长连接

那么,相比Http短连接,长连接技术能带来什么好处呢?

1. 不同域名的请求可以复用同一个长连接通道

以前我们不同域名的请求,需要做对应的DNS请求,然后建立对应的Http连接。上篇文章里说的Http连接池在不同域名下不可复用,需要重新建立连接。这些都是一些资源开销,但是如果通过长连接通道,那域名只是这个请求里的一个字段,可以直接复用同一条长连接通道。

2. 不依赖DNS,无DNS耗时和劫持等问题

上文中我们提到了HttpDNS,虽然它比系统DNS更优,但终归还是要做DNS操作。而长连接都是IP直接连接,因此没有DNS相关的开销和耗时。

3. 如果有大量网络请求,可以明显减少网络延时,节省带宽

对于大型App而言,存在繁多密集的网络请求,这中间就会存在非常多次的Http断开和重新连接,浪费了很多时间和带宽。而通过长连接通道的话,则没有这部分耗时,直接传输二进制数据即可,节省了每次连接里Header之类的带宽开销。

4. 服务端主动Push数据到客户端

对于上面提到的微信消息接收等场景,如果需要客户端主动去轮询,则会频繁发起请求,对于服务器会产生很大的负载压力,浪费带宽流量。而通过长连接,服务端可以主动把消息下发给客户端,做到最高实时性,且节省流量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jnmt4l8J-1630997908382)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1c2ba7115?imageView2/0/w/1280/h/960/ignore-error/1)]

III. 长连接何时会断开?

正常而言,长连接是不会断开的。大家可以自己试一试,两个socket建立连接,只要网络不变、一切正常,那么这两个socket可以一直互相传送数据,不会断开。

但是,在移动网络下,网络状态复杂多变,比如网络线路被切断、服务器宕机等,都会导致长连接中断。除了这些线路异常外,我们需要关注下面几个长连接断开原因:

1. 长连接所在进程被杀

这个很容易理解,如果我们的App切换到后台,那么系统随时可能将我们的App杀掉,这时长连接自然也就随之断开。

2. 用户切换网络

比如手机网络断开,或者发生Wi-Fi和蜂窝数据切换,这时会导致手机IP地址变更。而我们知道,TCP连接是基于IP + Port的,一旦IP变更,TCP连接自然也就失效了,或者说长连接也就相当于断开了。

3. 系统休眠等导致NAT超时

这里对NAT简单解释下,方便有的同学不太了解。当手机连接上网络时,网关会给我们分配一个IP地址,这个其实是内网IP,此时还未真正连接上公网,也连接不上服务器;如果想要连接公网,需要运营商将我们的内网IP映射成一个公网IP,有了公网IP,服务器就能与我们建立连接了。NAT指的就是这个映射过程。

也就是说,运营商会给每台设备分配一个公网IP,类似一张通信证。不过,随着连接网络的设备不断增多,网关负载也会不断加大,这时,运营商就会对一些不太活跃的设备进行公网IP回收了,如果下次这个设备需要连网,那就重新分配一个IP即可。

看似没问题,但实际上,如果我们的App在一段时间不活跃,发生了NAT超时,便会导致我们的公网IP失效,长连接也随之失效了。

4. DHCP 租期

DHCP 租期过期,如果没有及时续约,同样会导致IP地址失效。

综合而言,长连接在正常情况下是不会断开的,但是,一旦手机的IP地址失效,这时就不得不重新建立连接了。

IV. 如何建立稳定长连接?

上面我们提到了多种长连接断开的原因,那我们应该如何进行优化,尽可能保证长连接不断开,或者及时断开了,也要尽快重连呢?

1. Mars长连接独立进程

为了减少进程被杀的几率,在Mars的Demo代码里我们可以看到,它将长连接逻辑单独提取到了一个独立的进程里。这个进程只做网络交互,消耗的内存等资源自然较少,从而减少了被系统回收的概率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wy7BZFce-1630997908384)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1cb2b320e?imageView2/0/w/1280/h/960/ignore-error/1)]

图片来自《Android版微信后台保活实战分享(进程保活篇)》

2. 长连接进程复活

进程被杀难以避免,不过可以通过AlarmReceiver、 ConnectReceiver、BootReceiver,达到进程的及时唤醒。

当然,进程保活是一个比较大的话题,而且不恰当的进程保活也会对系统体验造成危害。这里就不深究了。

3. 心跳机制

对于心跳包很多人误以为只是用来定期告诉服务端我们的状态,实际并非如此。

上面我们提到了 NAT 超时,即如果App一段时间内不活跃,会导致运营商那里删除我们的公网IP映射关系,这会导致我们的TCP长连接断开。因此,我们需要通过心跳机制来保证App的活跃度,防止发生 NAT 超时。

4. 断开重连

在线上运行时,长连接很有可能会由于网络切换之类的原因断开。这时,我们需要尽快发现长连接断开,并立即重连。一般有下面几种做法:

  • 创建Receiver,监控网络状态,如果网络发生切换则立即重连;
  • 监控服务端心跳包回包,如果连续5次没有收到回包,则认为长连接已经失效;
  • 设置心跳包超时限制,如果超过时间还没有收到心跳回包,则重连,这种方式比较耗电;
  • 等socket IO异常抛出,不过耗时太长,需要15s左右才能发现。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OIqlH2st-1630997908385)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1e098a862?imageView2/0/w/1280/h/960/ignore-error/1)]

V. Mars智能心跳机制

1. 固定心跳机制

上面我们说了,心跳机制主要是为了防止 NAT 超时,外网IP地址失效。因此,一般的做法就是在NAT失效前,保证有心跳包发出。或者说,客户端应当以略小于NAT超时时间的间隔来发送心跳包。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BDUt4SFJ-1630997908385)(https://user-gold-cdn.xitu.io/2019/2/12/168df9c1ff69926e?imageView2/0/w/1280/h/960/ignore-error/1)]

早期的微信的心跳是4.5分钟发送一次心跳,可以不错的运行。

2. Mars智能心跳策略

在尽量不影响用户收消息及时性的前提下,根据网络类型自适应的找出保活信令TCP连接的尽可能大的心跳间隔,从而达到减少安卓微信因心跳引起的空中信道资源消耗,减少心跳Server的负载,以及减少部分因心跳引起的耗电。

自适应心跳

因此,在固定心跳机制下,微信又研究了一套动态计算心跳的方案,动态的探测最大的NAT超时时间,然后选定合适的心跳间隔区间去发送心跳包。这里说一下大致思路:

首先,如果心跳间隔越久,产生的负载和消耗也会越小。因此微信采用了自适应心跳:当找到一个有效心跳间隔后,我们主动去加大这个间隔,然后测试是否能成功,如果不能,则使用比上一次成功间隔稍短的时间作为间隔;否则继续加大间隔,直到找到可用的有效间隔。

那么,如何判断一个心跳间隔有效呢?微信采用的方案是使用固定短心跳直到满足三次连续短心跳成功,则认为这个间隔有效。

探测过程大致为:60秒短心跳,连续发3次后开始探测,90,120,150,180,210,240,270

前后台策略

另外,考虑到App在前后台对于长连接的需求是不同的。因此当微信在前台活跃态时,采用了固定心跳机制;在前台熄屏态或者后台活跃态(进入后台10分钟内)时,先用几次最小心跳维持长连接,然后进入自适应心跳机制;在后台稳定态(超过10分钟),则采用自适应心跳计算出来的最大心跳作为固定值。

如果在运行过程中,发生了心跳失败,则进行重连。同时将心跳间隔调整为断线前间隔减去20s,重新走自适应心跳;如果连续5次均失败,则以初始心跳180s继续测试。

Alarm对齐策略

对于Android系统而言,为了减少频繁唤醒系统导致的电量损耗,提供了Alarm对齐唤醒机制:把一定时间段内的多次Alarm唤醒合并成一次,减少系统被唤醒次数,增加待机时间。

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

数组,Framework ,混合跨平台开发,等

[外链图片转存中…(img-tG8h355p-1630997908386)]

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

[外链图片转存中…(img-Del35QM8-1630997908387)]

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 11:06:18  更:2021-09-08 11:08:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/27 1:38:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码