持久连接

2019-06-19  本文已影响0人  二斤寂寞

什么是持久连接?在事务处理结束之后仍然保持在打开状态的TCP连接被成为持久连接。非持久连接会在每个事务结束之后关闭,持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。重用持久连接,就可以避开缓慢的连接建立阶段。而且已经打开的连接还可以避免慢启动的拥挤适应阶段,以便更快地进行数据的传输。

可是这样会造成网络使用效率的降低,为什么呢?有这么几点原因

现在很多方案都会采用持久连接+新连接结合的方式,这种方式尽可能的减少了新建连接的浪费,同时当现有连接没有办法满足需求的时候,可以建立新连接满足需求,比较灵活。现有的持久连接类型有两种:
HTTP/1.0+的keep-alive和HTTP/1.1的persistent
keep-alive

keep-alive:
image.png

这个是百度首页的一个HTTP事务,可以看到有个首部connection:keep-alive,这个就是第一种持久连接了。下面来看下这个持久连接是怎么建立的:

image.png

这个就是请求的过程了:

客户端先发出请求,以connection:keep-alive的形式传向服务器,
如果服务器接受的请求的话响应中就会带有connection:keep- alive

当使用了connection:keep-alive时,可以使用keep-alive首部传递一些关于持久连接的参数:
timeout:表示持续时间,
max:表示希望还在这条持久连接上传输多少个HTTP服务
但是这些都不是承诺值,也就是说随时都可以反悔

keep-alive持久连接需要注意的一些地方:
哑代理和聪明的代理
哑代理只是单纯的转发请求,并不能进行解析处理、维持持久连接等其他工作,而聪明的代理可以解析接收到的报文同时可以维持持久连接。
image.png

如上图,当客户端与服务器之间存在不解析直接转发的代理时,connection:keep-alive这个首部是直接转发给服务器的,服务器接收了这个请求之后,就会向客户端发送带有connection:keep-alive的响应,同样盲代理不会解析响应,直接将全部响应转发回客户端。因为客户端收到了这个首部,就认为建立持久连接已经成功了,但是中间的”笨代理“,并不知道这些事情,笨代理只有一种行为模式:在转发请求和回送服务器响应请求之后就认为这次事务结束了,等待连接断开,而这时由于connection:keep-alive首部已经发送到服务器和客户端,双方都认为持久连接已经建立完成,这样就变成了两边认为持久连接OK而中间的哑代理等待连接断开的情况,这种情况下如果客户端再一次在这条连接上发送请求,请求就会在亚代理处停止,因为哑代理已经在等待连接关闭。这种状态会导致浏览器一直处于挂起状态,直到客户端或服务器之中一个连接超时,关闭连接为止,一段美好的牵手就这么没了(哑代理就是把内容原封不动的转发到代理)。

为了避免这种情况,现代的代理是不会转发connection:keep-alive这个首部的。
为了防止这个问题,网景提出了一个方案,采用插入Proxy-connection的方式,上图:

image.png
这个方案如何解决问题:

从上面所说的,我觉得这个方案其实就是相当于对中间代理的类型进行了一次判断。
但是这个方案只能解决中间只有一个代理的情况,如果聪明的任意一边还存在一个哑代理,那么仍会出现最开始的哑代理问题

persistent

HTTP/1.1的持久连接默认是开启的,只有首部中包含connection:close,才会事务结束之后关闭连接。当然服务器和客户端仍可以随时关闭持久连接。

当发送了connection:close首部之后客户端就没有办法在那条连接上发送更多的请求了。当然根据持久连接的特性,一定要传输正确的content-length。

还有根据HTTP/1.1的特性,是不应该和HTTP/1.0客户端建立持久连接的。最后,一定要做好重发的准备。

管道化连接

HTTP/1.1允许在持久连接上使用管道,这样就不用等待前一个请求的响应,直接在管道上发送第二个请求,在高延迟下,提高性能。

管道化连接的限制

参考文章:
https://www.cnblogs.com/littlewish/archive/2013/01/17/2865218.html

上一篇 下一篇

猜你喜欢

热点阅读