参考:《HTTP权威指南》
HTTP允许客户端和最终源端服务器之间存在一串HTTP中间实体(代理、高速缓存等)。可以从客户端开始,逐跳地将HTTP报文经过这些中间设备,转发到源端服务器上。(或者进行方向传输)
在某些情况下,两个相邻的HTTP应用程序会为它们共享的连接应用一组选项,HTTP的Connection首部字段中有一个由逗号分隔的连接标签列表,这些标签为此连接指定了一些不会传播到其他连接中的选项。
Connection首部承载3种不同类型的标签
1)HTTP首部字段名,列出了只与此连接有关的首部;
2)任意标签值,用于描述此连接的非标准选项
3)值close,说明操作完成之后需关闭这条持久连接
如果连接标签中包含了一个HTTP首部字段的名称,那么这个首部字段就包含了与一些连接有关的信息,不能将其转发出去。在将报文转发之前,必须删除Connection首部列出的所有首部字段。也即是,HTTP应用程序收到一条带有Connection首部的报文时,接收端会解析发送端请求的所有选项,并将其应用,然后会将此报文转发给下一跳地址之前,删除Connection首部以及Connection中列出的所有首部。二期额,可能还会有少量没有作为Connection首部值列出,但一定不能被代理转发的逐跳首部,其中包括Proxy-Authenticate,Proxy-Connection,Transfer-Encoding 和 Upgrade。
串行事务处理时延
如果每个事务都需要一条新的连接,那么连接时延和慢启动时延就会叠加起来。串行加载另一个缺点是,有些浏览器在对象加载完毕之前,无法获取对象尺寸,而且它们可能需要尺寸信息来决定对象放在屏幕的什么位置上,所有加载了足够多的对象之前,无法在屏幕上显示任何内容。
可以提高HTTP连接性能的方法:
并行连接
通过多条连接发起并发的HTTP请求。并行连接可以提高复合页面的传输速度,但其连接也有一些缺点
每个事务都会打开/关闭一条新的连接,会耗费时间和带宽。由于TCP慢启动特性存在,每条连接的性能都会有所降低。可打开的并行连接数量实际上是有限的
持久化连接
Web客户端经常会打开到同一个站点的连接。比如,一个Web页面上的大部分内嵌图片通常来自同一个Web站点,而且相当一部分指向其他对象的超链通常都指向同一个站点。初始化了对某服务器HTTP请求的应用程序很可能会不久的将来对那台服务器发起更多的请求,这种性质称为站点局部性。
因此,HTTP/1.1允许HTTP设备在事务处理结束之后将TCP连接保持在打开状态,以便为未来的HTTP请求重用现存的连接。在事务处理借宿之后仍然保持在打开状态的TCP连接称之为持久连接。持久连接会在不同事务之间保持打开状态,知道客户端或服务器决定其关闭为之。重用已对目标服务器打开的空闲持久连接,就可以避开缓慢的连接建立阶段。而且,已经打开的连接还可以避免慢启动的拥塞适应阶段,以便更快速地进行数据传输。所以,,持久连接降低了时延和连接建立的开销,将连接保持在已调谐状态,而且减少了打开连接的潜在数量。
持久连接和并行连接配合使用可能是最高效的方式。很多Web应用程序都会打开少量的并行连接,其中每个都是持久连接。持久连接有两种类型
1)HTTP/1.0 + keep-alive 连接
2) HTTP/1.1 + persistent 连接
HTTP/1.0 + keep-alive 连接
实现HTTP/1.0 keep-alive连接的客户端可以通过包含Connection:Keep-Alive 首部请求将一条连接保持在打开状态。
如果服务器愿意为下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有Connection:Keep-Alive首部,客户端就认为服务器不支持keep-alive,会在发回响应报文之后关闭连接。可以用 Keep-Alive通用首部中指定的、由逗号分隔的选项处理事务的数量。Keep-Alive首部完全是可选的,但是只有在提供Connection:keep-Alive时才能使用它。比如
Connection: Keep-Alive
Keep-Alive: max=5,timeout=120
HTTP/1.0中,keep-alive并不是默认使用的。客户端必须发送一个Connection:Keep-Alive请求首部来激活keep-alive连接。通过检测响应中是否Connection:Keep-Alive响应首部,客户端可以判断服务器是否会发出响应之后关闭连接。代理和网关必须执行Connection首部的规则。不应该与无法确定是否支持Connection首部的代理服务器建立keep-alive连接,以防止出现哑代理问题。
哪些不理解Connection首部,而且不知道沿着转发链路将其发送出去之前将该首部删除的代理,就叫盲中继。盲中继会是浏览器一直处于挂起状态,知道客户端或服务器将连接超时,并将其关闭为止。为此,引入一个名为Proxy-Connection的新首部,解决在客户端后面紧跟着一个盲中继所带来的问题。在显示配置了代理的情况下,现代浏览器都实现了Proxy-Connection,很多代理都能理解它。对多层次代理情况,Proxy-Connection仍然无法解决问题。
HTTP/1.1逐渐停止了对keep-alive连接的支持,用一种名为持久连接的改进型设计取代了它。持久连接的目的与keep-alive连接的目的相同,但是工作机制更优些。HTTP/1.1就吃连接在默认情况下是激活的,除非特别指明,否则HTTP/1.1假定所有的连接都是持久的,要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显示地添加一个Connection:close首部。
HTTP1.1客户端加载在收到响应后,除非响应中包含了Connection:close首部,不然HTTP/1.1连接就仍然维持在打开状态。但是,客户端和服务器仍然可以随时关闭空闲的连接。不发送Connection:close并不意味这服务器承诺永远将连接保持在打开状态。
只有当连接所有的报文都有正确的、自定义报文长度时,也就是说,实体主体部分的长度都和相应的Content-Length一致,或者用分块传输编码方式编码的,连接诶才能持久保持。
一个用户客服端对任何服务器或代理最多只能维护两条持久连接,以防服务器过载。代理可能需要更多到服务器的连接来支持并发用户的通信,所有如果有N个用户试图反问服务器的话,代理最多要维护2N条任意服务器或父代理的连接。
管道化连接
HTTP/1.1允许在持久连接上可选的使用请求管道。是相对于keep-alive连接的又一性能优化。在响应到达之前,可以将多条请求放入队列,当第一条请求通过网络流向服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能。
对管道连接的说明:
1)如果HTTP客户端无法确认连接是持久的,就不应该使用管道
2)必须按照与请求相同的顺序回送HTTP效应。
3)HTTP客户端必须做好连接会在任意时刻关闭的准备,还要准备好重发所有未完成管道化的请求。
4)出错的时候,管道连接会阻碍客户端了解服务器执行的是一些列管道化请求中的哪一些。由于无法安全地重试POST这样的非幂请求,所以出错时,就存在某些方法永远不会被执行的风险。
---------------------
作者:sugaryaruan
来源:CSDN
原文:https://blog.csdn.net/sugaryaruan/article/details/48922717
版权声明:本文为博主原创文章,转载请附上博文链接!
网友评论