【精选】HTTP:什么是队头阻塞以及怎么解决 您所在的位置:网站首页 tcp协议如何处理网络堵塞问题 【精选】HTTP:什么是队头阻塞以及怎么解决

【精选】HTTP:什么是队头阻塞以及怎么解决

2023-11-16 14:23| 来源: 网络整理| 查看: 265

三种连接 短连接

HTTP协议最初(0.9/1.0)是个非常简单的协议,通信给出也采用了简单的“请求-应答”方式。

它底层的数据传输基于TCP/IP,每次发送请求前需要先与服务器建立连接,收到相应报文后会立即关闭连接。

因为客户端和服务器的整个连接给出很短暂,不会与服务器保存长连接的状态,所以就称为“短连接”

短连接的缺点相当严重,因为在TCP协议里,建立连接和关闭连接都是非常“昂贵”的操作。TCP建立连接要有“三次挥手”,发送3个数据包,需要1.5个RTT;关闭连接是“四次挥手”,4个数据包需要2个RTT。

而HTTP的一次简单的“请求-响应”通常只需要4个包,如果不算服务器内部的处理时间,最多是2个RTT。这么算下来,浪费的时间就是“3÷5=60%”,有三分之二的时间被浪费掉了,传输效率低得惊人。 在这里插入图片描述

长连接

针对短连接暴露出的缺点,HTTP 协议就提出了“长连接”的通信方式,也叫“持久连接”(persistent connections)、“连接保活”(keep alive)、“连接复用”(connection reuse)

其实解决办法也很简单,用的就是“成本均摊”的思路,既然 TCP 的连接和关闭非常耗时间,那么就把这个时间成本由原来的一个“请求 - 应答”均摊到多个“请求 - 应答”上。因为TCP协议还有“慢启动”、“拥塞控制”等特性,通常新建立的“冷连接”会比打开了一段时间的“慢连接”要慢一些,所以长连接比短连接还多了这一层优势

利用HTTP的长连接特性对服务器发起大量请求,导致服务器最终耗尽资源“拒绝服务”,这也就是常说的DDos 在这里插入图片描述

在长连接中一个重要的问题是如何区分多个报文的开始和结束

最好总使用Content-Length头明确响应实体的长度,正确标记报文结束如果是流式传输,body长度不能立即确认,就必须使用分块传输编码 管道连接

pipeline是在长连接的基础上进了一步,可以批量发送请求批量接受响应,但因为存在一些问题,chrome、firefox等浏览器都没有实现它,已经被事实上“废弃”了

连接相关的头字段 由于长连接对性能的改善效果非常显著,所以在HTTP/1.1中的连接都会默认启用长连接。不需要用什么特殊的头字段指定,只要向服务器发送了第一次请求,后续的请求都会重复利用第一次打开的TCP连接,也就是长连接,在这个连接上收发数据。当然,我们也可以在请求头里明确地要求使用长连接机制,使用的字段是Connection,值是keep-alive不管客户端是否显示要求长连接,如果服务器支持长连接,它总会在响应报文中放一共Connection:keep-alive字段,告诉客户端:“我是支持长连接的,接下来就用这个TCP一直收发数据吧”

当然,长连接也有自己的缺点,问题就出现在“长”上:

因为TCP连接长时间不关闭,服务器必须在内存中保存它的状态,这就占用了服务器的资源。如果有大量的空闲长连接只连接不发送,就会很快耗尽服务器的资源,导致服务器无法为真正有需要的用户提高服务所以,长连接也需要在恰当的时间关闭,不能永远保持与服务器的连接,这在客户端或者服务器都可以做到 在客户端,可以在请求头中加上Connection:close字段,告诉服务器:“这次通信后就关闭连接”。服务器看到这个字段,就知道客户端要主动关闭连接,于是在响应报文里也加上这个字段,发送之后就调用socket API关闭TCP连接服务端通常不会主动关闭连接,但也可以使用一些策略,比如: 使用keepalive_timeout指令,设置长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开,避免空闲连接占用系统资源使用keepalive_requests指令,设置长连接上可以发送的最大请求次数。比如设置成 1000,那么当 在这个连接上处理了 1000 个请求后,也会主动断开连接 另外,客户端和服务器都可以在报文里附加通用头字段“Keep-Alive: timeout=value”,限定长连接的超时时间。但这个字段的约束力并不强,通信的双方可能并不会遵守,所以不太常见。 队头阻塞

队头阻塞与短连接/长连接无关,而是由HTTP基本的”请求-应答“模式所导致的:

因为HTTP规定报文必须”一发一收“,这就形成了一共先进先出的串行队列。队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本。 在这里插入图片描述 性能优化

因为“请求-应答”模型不能变,所以“队头阻塞”的问题在HTTP/1.1里面无法解决,只能缓解,有什么办法呢?

并发连接

并发连接是同时对一个域名发起多个长连接,用数量来解决质量的问题。

缺点是如果每个客户端都想自己快,建立很多个连接,用户数*并发数就会是个天文数字。服务器的资源根本就杠不住,或者被服务器认为是恶意连接,反而会造成“拒绝服务”所以,HTTP协议建议客户端使用并发,但不能“滥用”并发。 RFC2616 里明确限制每个客户端最多并发 2 个连接。不过实践证明这个数字实在是太小了,众多浏览器都“无视”标准,把这个上限提高到了 6~8。后来修订的RFC7230 也就“顺水推舟”,取消了这个“2”的限制。

”并发连接“ VS “高并发请求”

“高并发请求”是服务器端的概念,意思是同时有多个客户端连接服务器。“并发连接”是客户端的概念,意思是一个浏览器并发多个连接,访问服务器。 域名分片

但“并发连接”所压榨出的性能也跟不上高速发展的互联网无止境的需求,还有什么别的办法吗?

公司发展的太快了,员工越来越多,上下班打卡成了迫在眉睫的大问题。前台空间有限,放不下更多的打卡机了,怎么办?那就多开几个打卡的地方,每个楼层、办公区的入口也放上三四台打卡机,把人进一步分流,不要都往前台挤。这个就是“域名分片”(domain sharding)技术,还是用数量来解决质量的思路。HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如 shard1.chrono.com、shard2.chrono.com,而这些域名都指向同一台服务器www.chrono.com,这样实际长连接的数量就又上去了。 总结 早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;服务器会发送“Connection: keep-alive”字段表示启用了长连接;报文头里如果有“Connection: close”就意味着长连接即将关闭;过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;“队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”技术缓解。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有