从这次开始突然想尝试下新的笔记方式,昨天码完上一篇博客以后,突然收到了系统消息了,说不符合首页要求,仔细看了看要求的范围,赫然有一项没有“心得读书笔记”,估计就是这个躺枪了吧_(:з」∠)_。。。后来反省了下确实是这样,最开始做笔记的时候感觉这本说太"学术了",有很多信息如果靠自己描述的很怕弄掉了一些重点,后来想想其实也是,读书笔记这东西嘛,就是方便自己记忆的,即使笔记再全,真正消化掉的才是有用的,所以弄掉了的话也只能说你根本就没理解,即使记下来也没用咯。
闲话不多说,来看这次的内容:
持久连接
什么是持久连接?顾名思义,就是"持久"的连接。之前说到过,为了完成一个HTTP事务,服务器和客户端之间要建立一条TCP连接来传输报文,这个事务结束以后一般都会直接把它关闭,这是正常的模式。可是这样会造成网络使用效率的降低,为什么呢?有这么几点原因:
现在很多方案都会采用持久连接+新连接结合的方式,这种方式尽可能的减少了新建连接的浪费,同时当现有连接没有办法满足需求的时候,可以建立新连接满足需求,比较灵活。现有的持久连接类型有两种:HTTP/1.0+的keep-alive和HTTP/1.1的persistent.
先来看来keep-alive,先上图:
这个是百度首页的一个HTTP事务,可以看到有个首部connection:keep-alive,这个就是第一种持久连接了。下面来看下这个持久连接是怎么建立的:
这个就是请求的过程了:客户端先发出请求,以connection:keep-alive的形式传向服务器,如果服务器接受的请求的话响应中就会带有connection:keep- alive.
当使用了connection:keep-alive时,可以使用keep-alive首部传递一些关于持久连接的参数:timeout表示持续时间,max表示希望还在这条持久连接上传输多少个HTTP服务,但是这些都不是承诺值,也就是说随时都可以反悔。
接下来说说keep-alive持久连接需要注意的一些地方:
哑代理和聪明的代理
这里先说明下哑代理和聪明的代理的区别:哑代理只是单纯的转发请求,并不能进行解析处理、维持持久连接等其他工作,而聪明的代理可以解析接收到的报文同时可以维持持久连接。
如上图,当客户端与服务器之间存在不解析直接转发的代理时,connection:keep-alive这个首部是直接转发给服务器的,服务器接收了这个请求之后,就会向客户端发送带有connection:keep-alive的响应,同样盲代理不会解析响应,直接将全部响应转发回客户端。因为客户端收到了这个首部,就认为建立持久连接已经成功了,但是中间的”笨代理“,并不知道这些事情,笨代理只有一种行为模式:在转发请求和回送服务器响应请求之后就认为这次事务结束了,等待连接断开,而这时由于connection:keep-alive首部已经发送到服务器和客户端,双方都认为持久连接已经建立完成,这样就变成了两边认为持久连接OK而中间的哑代理等待连接断开的情况,这种情况下如果客户端再一次在这条连接上发送请求,请求就会在亚代理处停止,因为哑代理已经在等待连接关闭。这种状态会导致浏览器一直处于挂起状态,直到客户端或服务器之中一个连接超时,关闭连接为止,一段美好的牵手就这么没了(哑代理就是把内容原封不动的转发到代理)。
为了避免这种情况,现代的代理是不会转发connection:keep-alive这个首部的。
为了防止这个问题,网景提出了一个方案,采用插入Proxy-connection的方式,上图:
来看看这个方案如何解决问题:
从上面所说的,我觉得这个方案其实就是相当于对中间代理的类型进行了一次判断。
但是这个方案只能解决中间只有一个代理的情况,如果聪明的任意一边还存在一个哑代理,那么仍会出现最开始的哑代理问题。
HTTP/1.1的持久连接默认是开启的,只有首部中包含connection:close,才会事务结束之后关闭连接。当然服务器和客户端仍可以随时关闭持久连接。
当发送了connection:close首部之后客户端就没有办法在那条连接上发送更多的请求了。当然根据持久连接的特性,一定要传输正确的content-length。
还有根据HTTP/1.1的特性,是不应该和HTTP/1.0客户端建立持久连接的。最后,一定要做好重发的准备。
管道化连接
HTTP/1.1允许在持久连接上使用管道,这样就不用等待前一个请求的响应,直接在管道上发送第二个请求,在高延迟下,提高性能。
管道化连接的限制:
就到这里了,画着好累。。。