HTTP深入学习总结(4)——连接管理(中)

分类: 开发技术 | 作者: 尼莫船长 | 发表于 2013/10/17 3条评论


在上章,我简单写了一些HTTP底层链接的TCP实现,以及TCP链接存在的一些问题和瓶颈,本节主要讨论HTTP的一些基于链接优化点,还有简单说一些TCP链接管理的问题。
HTTP的链接方式大体上来说有4种形式:
1>串行事物处理(Serial Transaction Connection)
2>并行事物处理(Parallel Transaction Connection)
3>持久化链接(Persistence Connection)
4>管道化链接(Pipelined Connection)

下面分别来谈。
1,串行事务处理
串行事物链接比较好理解,就是在一条TCP链路上,一个接一个的传输HTTP的Req-Resp,这样的问题显而易见,在上一节我们提到过,每次HTTP事务,都要进行“握手”,而且由于前一个事物不能处理完毕,后面的事物必然没法继续进行传输,所以,这样的链接方式已经过时了,几乎在现在的应用中不会出现了……

===============插播广告开始=============

HTTP首部 关键字 Connection:

这个首部的项目有点略难理解,比较绕,HTTP的官方文档上是对其这样定义的:
类型: 通用首部 (说明req/resp均适用)
基本语法: Connection:1# (connection token)
举例: Connection:close
注释: 扩展HTTP/1.0 的 keep-alive客户端,keep-alive用于连接控制信息。HTTP/1.1中,Connection首部的值是一个标记列表,这些标记列表对应各种首部名称,应用程序收到带有Connection首部标记的HTTP/1.1报文后,应该对其列表进行解析,病删除报文中所有在Connection列表中出现的首部,它主要用于有代理网络环境,这样服务器或者其他其他代理服务器就可以指定不应传递的逐跳首部。

晕了没? 晕了正常。O(∩_∩)O~

假如有这样一个Resp:
传输链路为 Server —(Resp)—>Proxy ——> Client

	HTTP/1.1 200 ok
	Cache-control : 200
	Connection: meter,close,set-list-open
	Meter:max-users=30,dont-report
	

Connection 表明了3个含义:
1,告知Proxy 服务器,传送到Clinet之前,不要传输Meter首部(meter起作用);
2,告知Proxy 服务器,传送这个Resp以后,关闭链路(close的作用);
3,告知Proxy 服务器,采用set-list-open选项;

结合上述实例,我们得到如下3个相对不那么晦涩的Connection功能:
1,如果首部有Connection对应的选项了,那么不要传输,要过滤掉;
2,传输完毕以后,关闭这条链路(特定关键字 close);
3,如果包含了不在首部中出现的值,那么这个值可以作为一个非HTTP定义的选项;

===============插播广告结束=============

2,并行事务处理
多个TCP链接并发HTTP请求

这并不是一个很好的解决方案,举例子,比如一个web页面,上面4个图片,每个都是一个HTTP事物,这样加载这样一个web页面,就需要并发建立4条TCP链接,看上去好像提升了页面访问速度,但是,可能造成:
1>客户端资源瓶颈导致请求失败。比如带宽耗尽,客户端内存耗尽等等。
2>server端的压力过大,如果20个客户端同时访问,就是4*20=80个TCP并发……
所以,看起来这也不是一个太好的解决方案。

btw: 一般浏览器其实是并发的处理HTTP事物的,绝大多数浏览器会默认有4个并发,当然这个值不是绝对的。但是数量绝对不会太大。

3,持久化链接
重用TCP链接,以便消除链接的握手、关闭时延。这是最主流的做法了,所以会写很多……
一般来说,我们访问某一个网站,可能会浏览很长一段时间,比如你看了我的博客主页,然后发现写的好棒,然后继续看下去……^_^ 于是在HTTP/1.0版本之后允许在HTTP事物处理完毕之后,允许TCP链接保持链接状态,而非关闭,直到客户端主动关闭。这样的特性就是持久化链接,也就是传说中的: Connection: keep-alive
但是,在HTTP/1.0中
使用keep-alive会发生很多问题,由于HTTP/1.0现在使用的不多了,所以问题我就不写了,太多了,如果感兴趣可以自己去google,或者大家可以自己考虑一下这样的场景:

Clinet<——>Proxy1<——>Proxy2<——>Server

在这样的链路上传送Keep-alive的HTTP事物会有什么问题? 为神马会有Proxy-Connection这样的首部会被加进来。

在HTTP/1.1版本中,keep-alive被直接改成了“持久化”链接,同时调整了链接机制: 所有的HTTP链路默认都是持久链接的,除非显示的关闭它; 在报文中的首部添加 Connection:close首部, 关闭链路,这个是HTTP1.1版本和1.0版本的显示区别;
HTTP/1.1的客户端,除非受到了 Connection:close的Resp 首部,否则链路会被维持,这个是最典型的特征。

持久化链接有如下的限制和规则:
1>发送包含 Connection:close 的Req之后,Client就无法在这条链路上继续发送Req了;
2>Client如果不想发送任何Req了,那么在最后一个Req的首部上应该加上Connection:close;
3>只有链路上的报文都是正确的,即:报文符合Content-length和mutilpart传输定义的条件下,链路才会被保持;
4>HTTP/1.1的Proxy必须能分别管理与Clinet和Server的持久化链接;
5>HTTP/1.1与HTTP/1.0的不应该建立持久化链接;
6>HTTP/1.1的设备可以在任何时间关闭链路,即便是出错或者暴力关闭;
7>HTTP/1.1必须能够从异步的关闭中恢复出来,只要不存在可能的累积后的副作用,Client都应该重试这条链路;
8>除非重复发送请求会有副作用,否则Client如果在收到整个Resp之前连接关闭,那么Client必须重新发送Req;
9>一个Client对任何Server或者Proxy Server最多只能维持两条持久化链接,以防止Server过载;

===============插播广告开始=============

幂等(Idempotent):

这本是一个数学概念……是指被自己作用还是自己的元素,或者被自己复合的函数还是自己的函数 ^_^我代数一般般……
HTTP中的幂等,是指一个HTTP事物,不管执行1次还是多次,得到的结果都是相同的,我们称之为幂等的。
例如:Get、Head、Put、Trace、Option、Delete方法;而典型的POST方法就不是幂等的。

===============插播广告结束=============

4,管道化链接
通过共享的TCP链接并发的HTTP请求

HTTP/1.1在持久化链接的基础上,允许使用“请求管道”(request pipelining),这是对keep-alive的进一步优化,在保持长连接的基础上,在response到达之前,允许客户端将更多的request放入请求队列。这样可以大大提升网络的环回时间,提升性能。

对于管道化链接有如下的限制:
1>如果不能确认HTTP链接是持久的,那么就不能使用管道;
2>必须按照请求发送的顺序返回对应的response,否则会导致req-resp不匹配的问题;
3>HTTP client必须有管道被随时关闭的容错处理,同时还应该有断连后,积压的resp重发机制;
4>HTTP client不能用管道发送具有产生副作用的请求,例如POST;

移动设备快速阅读本文:
  请扫描二维码  -->

谁勇敢地经受过青春之火的洗礼,谁就毫不畏惧晚年的严寒冰霜。——兰多

» 本文链接地址:http://www.wanghaoyan.com/?p=198 » 英雄不问来路,转载请注明出处,谢谢。
» 您也可以订阅本站:RSS 2.0

Tag:
« »