HTTP 持久连接 请求头 Connection: Keep-Alive 如何管理跨代理服务器的长短连接?

下面将介绍长连接和短连接的区别,以及客户端和源服务器有多个代理服务器,这些代理服务器会如何处理长连接。

HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。

因此,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connectionreuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP 连接状态。

管线化

持久连接使得多数请求以管线化(pipelining)方式发送成为可能。

从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。 这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

 

 

HTTP 连接的常见流程


首先在浏览器中输入了url之后,会根据DNS这里解析出来IP地址,根据IP地址和端口号码,浏览器就会向服务器建立TCP的连接,在这个连接上就会发送一个请求,服务器必须在这个连接上返回一个响应,最后浏览器再关闭连接。

上面就是一个完整的请求过程,也是一个短连接的流程。

从 TCP 编程上看 HTTP 请求处理


服务器需要先建立socket,用80绑定,然后listen监听,然后accept等待新的连接的建立。

而客户端需要创建新的socket,然后连接到服务器上,服务器上读取到这个请求之后,客户端再去调用write方法发送这个请求,然后调用read方法去读取响应。

服务器处理完请求之后,就会发送响应,就会双方各自关闭连接。

短连接和长连接


在谈长连接和短连接需要谈一个概念,就是事务的概念,假定一个事务就是一个请求对应着一个响应。

什么是短连接呢?从左到右的时间线上来看,每次建立一个连接,然后处理请求,得到响应,这个连接就关闭了。处理事务2的时候,又发起请求2和响应2,连接2也接着关闭,同理连接3。这就是一个串行的短连接。

长连接,客户端和服务器建立了一个连接,执行完第一个事务之后,接着执行第二个事务,以此类推,一直执行在同一个连接上,这叫做持久的长连接。

长连接是由什么决定的呢?并不是所有的浏览器和客户端都支撑长连接,特别是有些古老的服务器不支持长连接,客户端和服务器要去沟通。

沟通就通过connection头部,connection头部当中添加了keepalive值的时候表明长连接的意思,如果是请求中包含了keepalive,表示客户端希望使用长连接,如果服务器也支持长连接会响应当中也添加connection keepalive,接下来就可以复用这个长连接去发送请求了。

HTTP 1.1当中是默认支持长连接的,所以传递connection keepalive其实意义不大。

如果明确表示不支持长连接,特别是在HTTP1.1当中,可以在connection加上close,就表示这是一个短连接。

connection除了表示长连接和短连接之外,还有一个功能,就是对connection后面列出的头部,对代理服务器有些要求,代理服务器在转发这个请求的时候,不要转发connection列出的头部,比如列出了cookie,代理服务器转发给源服务器的时候需要将cookie的头部去除掉。

Connection 仅针对当前连接有效


connection如果有中间代理服务器的时候,connection并不是代表对完整的链路上都要使用长连接,而表示对当前的TCP连接,也就是客户端和代理服务器之间,这条连接使用的是长连接,其实客户端和原服务器之间有很多代理服务器,比如正向/反向代理服务器。

客户端的keepalive表示与第一个代理服务器使用长连接,代理服务器和代理服务器是不使用长连接的,比如版本比较老,那么就不想使用长连接,反向代理服务器和内网的原始服务器之间都支持长连接,那他们就使用黄色的长连接了。(第一个代理服务器不支持长连接,所以它告诉客户端虽然你和我要使用keepalive,但是我是不支持的,所以我返回了connection close,最终客户端和第一个代理服务器之间使用的是短连接,因为代理服务器不支持长连接,代理和代理服务器之间使用的是短连接)

反向代理服务器和正向代理服务器之间使用的就是短连接,正向代理服务器不支持长连接,告诉客户端说虽然你想要使用keepalive,但是我是不支持的,所以返回connection close。

那么上面就第一个代理服务器不支持长连接,但是我认识connection这个头部,它知道客户端想用长连接,而接下来我不支持长连接,那么我给下游传入connection close。

代理服务器对长连接的支持


中间就是非常陈旧的代理服务器,它完全不认识connection keepalive,当然它也不可能支持长连接,这个时候客户端发来的keepalive,它就会原封不动的发到原服务器上面,原服务器收到了keepalive以为代理服务器是想建立长连接,而它也支持长连接,它也回了一个keepalive,这样陈旧的代理服务器不认识这个,然后原封不动的转给客户端。

这样客户端就以为它建立的是长连接,原服务器也以为它建立的是长连接,但是实际上中间的代理服务器两端都使用短连接,它不支持长连接,所以就会导致代理服务器出错之后导致客户端在复用长连接的时候连接被意外断开,或者直接收不到响应。

如何解决这个问题,引入新的头部proxy-connection,如果是陈旧的代理服务器,它收到这样的头部之后,它其实不识别就原封不动的转发,但是本身还是要退化为短连接的。

而新版本的代理服务器就能够理解这个头部。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值