前面的话
在tcp协议中有队头阻塞问题,但是HTTP1.1中也有类型的队头阻塞问题,小柒在这里总结一下。
TCP队头阻塞
TCP的队头阻塞发生: 当一个TCP分节丢失的时候,因为TCP是可靠传输,所有后续分节将被接收端一直保存,直到丢失的第一个分节被发送端重传并且到达接受端为止才会继续被传输。
这种可靠的传输机制确保接收应用进程能够按照发送端的发送顺序接受数据。虽然可靠但是也有不利之处。
比如说,客户端向服务端请求3幅图片,为了营造这几幅图像在用户屏幕上并行显示的效果,服务器先发送第一幅图像的一个断片,再发送第二幅图像的一个断片,然后再发送第三幅图像的一个断片;服务器重复这个过程,直到这3幅图像全部成功地发送到浏览器为止。
如果第一幅图的某个断片的TCP分节丢失,客户端将保持已到达的不按序的所有数据,直到丢失的分节重传成功。这样一来延迟了第一幅图像的数据传送,也影响了后面两幅图像数据递送。
HTTP队头阻塞
HTTP1.1增加了管线化技术,允许客户端不用等到服务器的响应就能发送下一个请求。目的为了在一次TCP连接上可以并行发送多个请求,来提高网络利用率。但是它有一个很大的缺点,服务器必须安装请求的顺序来响应。即后续请求的响应必须等到第一个响应发送之后才能发送,即使后续响应已经完成。这就是HTTP队头阻塞的来由。
如何解决队头阻塞
解决HTTP队头阻塞问题
对于HTTP1.1中管线化技术导致的请求队头阻塞,可以使用HTTP2.0解决。
HTTP2.0增加了一层二进制分帧层,引入了帧,消息,流的概念。每个请求/响应成为消息,消息可分为多帧,每个帧在流中进行传输,一个tcp连接可以有多个流。各个帧在到达之后重组为消息,这样就避免了请求队头阻塞。
当然HTTP2.0的底层还是使用TCP协议,仍会出现TCP队头阻塞。
解决TCP队头阻塞问题
TCP中的队头阻塞的产生是由TCP自身的实现机制决定的,无法避免。想要在应用程序当中避免TCP队头阻塞带来的影响,只有舍弃TCP协议。
比如google推出的quic协议,在某种程度上可以说避免了TCP中的队头阻塞,因为它根本不使用TCP协议,而是在UDP协议的基础上实现了可靠传输。而UDP是面向数据报的协议,数据报之间不会有阻塞约束。
- QUIC是一个在UDP之上的伪TCP +TLS +HTTP/2的多路复用的协议
注意:(UDP不管顺序,不管丢包(QUIC的一个任务是要像TCP一样稳定,所以QUIC有自己的丢包重传的机制))
参考文章: