app中的长连接与实现方式

来源:互联网 发布:c语言putchar函数 编辑:程序博客网 时间:2024/04/29 01:08
http://mrpeak.cn/blog/http2/   --- 原文
http2.0的好处不仅仅是multiplexing,请求压缩,优先级控制,server push等等都是亮点。

 解决连接无法复用

http1.0协议头里可以设置Connection:Keep-Alive。在header里设置Keep-Alive可以在一定时间内复用连 接,具体复用时间的长短可以由服务器控制,一般在15s左右。到http1.1之后Connection的默认值就是Keep-Alive,如果要关闭连 接复用需要显式的设置Connection:Close。一段时间内的连接复用对PC端浏览器的体验帮助很大,因为大部分的请求在集中在一小段时间以内。 但对移动app来说,成效不大,app端的请求比较分散且时间跨度相对较大。所以移动端app一般会从应用层寻求其它解决方案,长连接方案或者伪长连接方 案:

方案一:基于tcp的长链接

现在越来越多的移动端app都会建立一条自己的长链接通道,通道的实现是基于tcp协议。基于tcp的socket编程技术难度相对复杂很多,而且 需要自己制定协议,但带来的回报也很大。信息的上报和推送变得更及时,在请求量爆发的时间点还能减轻服务器压力(http短连接模式会频繁的创建和销毁连 接)。不止是IM app有这样的通道,像淘宝这类电商类app都有自己的专属长连接通道了。现在业界也有不少成熟的方案可供选择了,google的protobuf就是其 中之一。

方案二:http long-polling

long-polling可以用下图表示:


[图2]


客户端在初始状态就会发送一个polling请求到服务器,服务器并不会马上返回业务数据,而是等待有新的业务数据产生的时候再返回。所以连接会一 直被保持,一旦结束马上又会发起一个新的polling请求,如此反复,所以一直会有一个连接被保持。服务器有新的内容产生的时候,并不需要等待客户端建 立一个新的连接。做法虽然简单,但有些难题需要攻克才能实现稳定可靠的业务框架:

  • 和传统的http短链接相比,长连接会在用户增长的时候极大的增加服务器压力
  • 移动端网络环境复杂,像wifi和4g的网络切换,进电梯导致网络临时断掉等,这些场景都需要考虑怎么重建健康的连接通道。
  • 这种polling的方式稳定性并不好,需要做好数据可靠性的保证,比如重发和ack机制。
  • polling的response有可能会被中间代理cache住,要处理好业务数据的过期机制。

long-polling方式还有一些缺点是无法克服的,比如每次新的请求都会带上重复的header信息,还有数据通道是单向的,主动权掌握在server这边,客户端有新的业务请求的时候无法及时传送。

方案三:http streaming

http streaming流程大致如下:


同long-polling不同的是,server并不会结束初始的streaming请求,而是持续的通过这个通道返回最新的业务数据。显然这个 数据通道也是单向的。streaming是通过在server response的头部里增加”Transfer Encoding: chunked”来告诉客户端后续还会有新的数据到来。除了和long-polling相同的难点之外,streaming还有几个缺陷:
  • 有些代理服务器会等待服务器的response结束之后才会将结果推送到请求客户端。对于streaming这种永远不会结束的方式来说,客户端就会一直处于等待response的过程中。
  • 业务数据无法按照请求来做分割,所以客户端没收到一块数据都需要自己做协议解析,也就是说要做自己的协议定制。

streaming不会产生重复的header数据。

方案四:web socket


WebSocket和传统的tcp socket连接相似,也是基于tcp协议,提供双向的数据通道。WebSocket优势在于提供了message的概念,比基于字节流的tcp socket使用更简单,同时又提供了传统的http所缺少的长连接功能。不过WebSocket相对较新,2010年才起草,并不是所有的浏览器都提供 了支持。各大浏览器厂商最新的版本都提供了支持。

2. 开拓者SPDY

http1.0和1.1虽然存在这么多问题,业界也想出了各种优化的手段,但这些方法手段都是在尝试绕开协议本身的缺陷,都有种隔靴搔痒,治标不治 本的感觉。直到2012年google如一声惊雷提出了SPDY的方案,大家才开始从正面看待和解决老版本http协议本身的问题,这也直接加速了 http2.0的诞生。实际上,http2.0是以SPDY为原型进行讨论和标准化的。为了给http2.0让路,google已决定在2016年不再继 续支持SPDY开发,但在http2.0出生之前,SPDY已经有了相当规模的应用,作为一个过渡方案恐怕在还将一段时间内继续存在。现在不少app客户 端和server都已经使用了SPDY来提升体验,http2.0在老的设备和系统上还无法使用(iOS系统只有在iOS9+上才支持),所以可以预见未 来几年spdy将和http2.0共同服务的情况。

2.1 SPDY的目标

SPDY的目标在一开始就是瞄准http1.x的痛点,即延迟和安全性。我们上面通篇都在讨论延迟,至于安全性,由于http是明文协议,其安全性 也一直被业界诟病,不过这是另一个大的话题。如果以降低延迟为目标,应用层的http和传输层的tcp都是都有调整的空间,不过tcp作为更底层协议存在 已达数十年之久,其实现已深植全球的网络基础设施当中,如果要动必然伤经动骨,业界响应度必然不高,所以SPDY的手术刀对准的是http。

  • 降低延迟,客户端的单连接单请求,server的FIFO响应队列都是延迟的大头。
  • http最初设计都是客户端发起请求,然后server响应,server无法主动push内容到客户端。
  • 压缩http header,http1.x的header越来越膨胀,cookie和user agent很容易让header的size增至1kb大小,甚至更多。而且由于http的无状态特性,header必须每次request都重复携带,很浪费流量。

为了增加业界响应的可能性,聪明的google一开始就避开了从传输层动手,而且打算利用开源社区的力量以提高扩散的力度,对于协议使用者来说,也 只需要在请求的header里设置user agent,然后在server端做好支持即可,极大的降低了部署的难度。SPDY的设计如下:





SPDY位于HTTP之下,TCP和SSL之上,这样可以轻松兼容老版本的HTTP协议(将http1.x的内容封装成一种新的frame格式),同时可以使用已有的SSL功能。SPDY的功能可以分为基础功能和高级功能两部分,基础功能默认启用,高级功能需要手动启用。

SPDY基础功能

  • 多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了http1.x holb(head of line blocking)的问题,降低了延迟同时提高了带宽的利用率。
  • 请求优先级(request prioritization)。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置 优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保 证用户能第一时间看到网页内容。
  • header压缩。前面提到过几次http1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。SPDY对header的压缩率可以达到80%以上,低带宽环境下效果很大。

SPDY高级功能

  • server推送(server push)。http1.x只能由客户端发起请求,然后服务器被动的发送response。开启server push之后,server通过X-Associated-Content header(X-开头的header都属于非标准的,自定义header)告知客户端会有新的内容推送过来。在用户第一次打开网站首页的时 候,server将资源主动推送过来可以极大的提升用户体验。
  • server暗示(server hint)。和server push不同的是,server hint并不会主动推送内容,只是告诉有新的内容产生,内容的下载还是需要客户端主动发起请求。server hint通过X-Subresources header来通知,一般应用场景是客户端需要先查询server状态,然后再下载资源,可以节约一次查询请求。


3. 救世主HTTP2.0


SPDY的诞生和表现说明了两件事情:一是在现有互联网设施基础和http协议广泛使用的前提下,是可以通过修改协议层来优化http1.x的。二 是针对http1.x的修改确实效果明显而且业界反馈很好。正是这两点让IETF(Internet Enginerring Task Force)开始正式考虑制定HTTP2.0的计划,最后决定以SPDY/3为蓝图起草HTTP2.0,SPDY的部分设计人员也被邀请参与了 HTTP2.0的设计

3.1 HTTP2.0需要考虑的问题

HTTP2.0与SPDY的起点不同,SPDY可以说是google的“玩具”,最早出现在自家的chrome浏览器和server上,好不好玩以 及别人会不会跟着一起玩对google来说无关痛痒。但HTTP2.0作为业界标准还没出生就是众人瞩目的焦点,一开始如果有什么瑕疵或者不兼容的问题影 响可能又是数十年之久,所以考虑的问题和角度要非常之广。我们来看下HTTP2.0一些重要的设计前提:

  • 客户端向server发送request这种基本模型不会变。
  • 老的scheme不会变,使用http://和https://的服务和应用不会要做任何更改,不会有http2://。
  • 使用http1.x的客户端和服务器可以无缝的通过代理方式转接到http2.0上。
  • 不识别http2.0的代理服务器可以将请求降级到http1.x。

因为客户端和server之间在确立使用http1.x还是http2.0之前,必须要要确认对方是否支持http2.0,所以这里必须要有个协商的过 程。最简单的协商也要有一问一答,客户端问server答,即使这种最简单的方式也多了一个RTT的延迟,我们之所以要修改http1.x就是为了降低延 迟,显然这个RTT我们是无法接受的。google制定SPDY的时候也遇到了这个问题,他们的办法是强制SPDY走https,在SSL层完成这个协商 过程。ssl层的协商在http协议通信之前,所以是最适合的载体。google为此做了一个tls的拓展,叫NPN(Next Protocol Negotiation),从名字上也可以看出,这个拓展主要目的就是为了协商下一个要使用的协议。HTTP2.0虽然也采用了相同的方式,不过 HTTP2.0经过激烈的讨论,最终还是没有强制HTTP2.0要走ssl层,大部分浏览器厂商(除了IE)却只实现了基于https的2.0协议。 HTTP2.0没有使用NPN,而是另一个tls的拓展叫ALPN(Application Layer Protocol Negotiation)。SPDY也打算从NPN迁移到ALPN了。

各浏览器(除了IE)之所以只实现了基于SSL的HTTP2.0,另一个原因是走SSL请求的成功率会更高,被SSL封装的request不会被监 听和修改,这样网络中间的网络设备就无法基于http1.x的认知去干涉修改request,http2.0的request如果被意外的修改,请求的成 功率自然会下降。


HTTP2.0协议没有强制使用SSL是因为听到了很多的反对声音,毕竟https和http相比,在不优化的前提下性能差了不少,要把https 优化到几乎不增加延迟的程度又需要花费不少力气。IETF面对这种两难的处境做了妥协,但大部分浏览器厂商(除了IE)并不买帐,他们只认 https2.0。对于app开发者来说,他们可以坚持使用没有ssl的http2.0,不过要承担一个多余的RTT延迟和请求可能被破坏的代价。


4.2 Android下http现状

android和iOS情况类似,http2.0只能在新系统下支持,spdy作为过渡方案仍然有存在的必要。

对于使用webview的app来说,需要基于chrome内核的webview才能支持spdy和http2.0,而android系统的webview是从android4.4(KitKat)才改成基于chrome内核的。


对于使用native api调用的http请求来说,okhttp是同时支持spdy和http2.0的可行方案。如果使用ALPN,okhttp要求android系统 5.0+(实际上,android4.4上就有了ALPN的实现,不过有bug,知道5.0才正式修复),如果使用NPN,可以从android4.0+ 开始支持,不过NPN也是属于将要被淘汰的协议。
0 0
原创粉丝点击