HTTP发展的根本原因----连接无法复用和head of line blocking

HTTP发展的根本原因----连接无法复用和head of line blocking

HTTP发展的根本原因

HTTP优化的2个主要因素是带宽和延迟,其中随着网络的发展,带宽基本可以满足,那核心问题就转变为如何降低延迟. 根据HTTP1.0可以发现,影响延迟的2个关键在于连接无法复用head of line blocking.

  • 连接无法复用: 会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件大批量请求影响较大。
  • head of line blocking: 会导致带宽无法被充分利用,以及后续健康请求被阻塞。假设有5个请求同时发出,对于HTTP1.0的实现, 在第一个请求没有收到回复之前,后续从应用层发出的请求只能排队,请求2,3,4,5只能等请求1的response回来之后才能逐个发出。网络通畅的时候性能影响不大,一旦请求1的request因为什么原因没有抵达服务器,或者response因为网络阻塞没有及时返回,影响的就是所有后续请求,问题就变得比较严重了。

    ii

1. 解决连接无法复用问题

  • 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可以用下图表示:客户端在初始状态就会发送一个polling请求到服务器,服务器并不会马上返回业务数据,而是等待有新的业务数据产生的时候再返回。所以连接会一直被保持,一旦结束马上又会发起一个新的polling请求,如此反复,所以一直会有一个连接被保持。服务器有新的内容产生的时候,并不需要等待客户端建立一个新的连接。缺点是: long-polling在用户增长的时候极大的增加服务器压力;polling的方式稳定性并不好,需要做好数据可靠性的保证,比如重发和ack机制。polling的response有可能会被中间代理cache住,要处理好业务数据的过期机制。long-polling方式还有一些缺点是无法克服的,比如每次新的请求都会带上重复的header信息,还有数据通道是单向的,主动权掌握在server这边,客户端有新的业务请求的时候无法及时传送。
ii
  • 方案三:http streaming: http streaming流程大致如下:同long-polling不同的是,server并不会结束初始的streaming请求,而是持续的通过这个通道返回最新的业务数据。显然这个数据通道也是单向的。streaming是通过在server response的头部里增加”Transfer Encoding: chunked”来告诉客户端后续还会有新的数据到来。除了和long-polling相同的难点之外,streaming还有几个缺点:有些代理服务器会等待服务器的response结束之后才会将结果推送到请求客户端。对于streaming这种永远不会结束的方式来说,客户端就会一直处于等待response的过程中。业务数据无法按照请求来做分割,所以客户端没收到一块数据都需要自己做协议解析,也就是说要做自己的协议定制。streaming不会产生重复的header数据。
ii
  • 方案四:web socket: WebSocket和传统的tcp socket连接相似,也是基于tcp协议,提供双向的数据通道。WebSocket优势在于提供了message的概念,比基于字节流的tcp socket使用更简单,同时又提供了传统的http所缺少的长连接功能。不过WebSocket相对较新,2010年才起草,并不是所有的浏览器都提供了支持。各大浏览器厂商最新的版本都提供了支持。

2. 解决head of line blocking问题

HTTP1.1和HTTP2.0的最大优势就是对于头部阻塞问题的解决.

  • HTTP1.1的解决方案 ---- http pipelining: 和图一相比最大的差别是,请求2,3不用等请求1的response返回之后才发出,而是几乎在同一时间把request发向了服务器。2,3及所有后续共用该连接的请求节约了等待的时间,极大的降低了整体延迟。缺点: pipelining只能适用于http1.1,一般来说,支持http1.1的server都要求支持pipelining。 只有幂等的请求(GET,HEAD)能使用pipelining,非幂等请求比如POST不能使用,因为请求之间可能会存在先后依赖关系。head of line blocking并没有完全得到解决,server的response还是要求依次返回,遵循FIFO(first in first out)原则。绝大部分的http代理服务器不支持pipelining。和不支持pipelining的老服务器协商有问题。可能会导致新的Front of queue blocking问题。正是因为有这么多的问题,各大浏览器厂商要么是根本就不支持pipelining,要么就是默认关掉了pipelining机制,而且启用的条件十分苛刻。
ii
  • HTTP2.0的解决方案 ---- 多路复用multiplexing, 请求优先级request prioritization, 首部压缩header packet,服务器推送server push HTTP2.0的目标在一开始就是瞄准http1.x的痛点,即延迟和安全性。我们上面通篇都在讨论延迟,至于安全性,由于http是明文协议,其安全性也一直被业界诟病,不过这是另一个大的话题。如果以降低延迟为目标,应用层的http和传输层的tcp都是都有调整的空间,不过tcp作为更底层协议存在已达数十年之久,其实现已深植全球的网络基础设施当中,如果要动必然伤经动骨,业界响应度必然不高,所以HTTP2.0的手术刀对准的是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端做好支持即可,极大的降低了部署的难度。
ii

相关链接

[1] HTTP 0.9 HTTP 1.0 HTTP 1.1 HTTP 2.0区别
[2] http2.0深入理解
[3] HTTP 2.0 协议详解
[4] http2.0
[5] HTTP1.0、HTTP1.1 和 HTTP2.0 的区别

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值