定义
队头阻塞是指:当单个(慢)对象阻止其他/后续的对象前进时。
举例
假设你去超市买东西,超市只有一个收银台,正在结算的客户因为办理会员,从包里找身份证迟迟没找到,就会耽误后面排队的人结算。另一个例子是在单行道上,发生一起车祸可能会导致整条道路堵塞很长时间。因此,在“头部”的单一问题可以阻塞整条线。
浏览器队头阻塞问题
在浏览器中打开一个页面进行操作时,可能会发出多个网络请求,假设其中的若干请求响应较慢(比如10s以上),继续页面上的操作可能就会收到阻塞。
分析
HTTP1.0所实现的TCP连接中,HTTP请求必须等待前一个请求响应之后,才能发送,也就是说,如果在一个TCP通道中如果某个HTTP请求的响应因为某个原因没有及时返回,后面的响应会被阻塞,这就是队头阻塞问题,它是网络请求性能问题阻塞页面响应的源头。HTTP1.1时代,TCP支持了长连接,每个TCP连接可以处理多个HTTP请求,用于解决队头阻塞问题。
HTTP 协议建议客户端使用并发长连接,这个并发指的是TCP并发。RFC2616 里明确限制每个客户端可以建立两个长连接,需要说明的是,客户端建立长连接的个数是针对域名发起的。但是一般浏览器会把并发连接数增加到6到8个,谷歌浏览器是6个,也就是页面中如果针对同一个域名有多个HTTP请求,谷歌浏览器会针对这个域名建立6个TCP长连接,在每个长连接里面再去处理HTTP请求,但是这种方案其实对服务器的挑战非常大,有些Web优化方案中还会突破6到8的限制,那就是域名切片,因为长连接是针对的同一个域名,那么如果开发人员将资源分布在不同的域名上,那么长连接的数量也是可以被突破的。假设客户端在交互过程中发出的请求足够多,且响应延时严重,长连接的数量可能被耗尽,导致更多的请求无法发出,最终阻塞客户端,造成用户体验问题。
解决办法
-
采用域名切片。如果有需要、有条件,页面请求非常多的情况下,可将部分网络请求进行域名分片,也就是将请求落到不同的域名下,可突破原有长连接的数量限制。
2) 提升服务端的响应速度。如果流畅的响应体验比较重要,服务端应遵循快速响应原则,超时则认为失败,错误则快速返回,甚至服务端可以请求进行异步处理,只要接收到数据就返回成功,并设置严格的响应超时时间。
3) 减少请求数量。条件允许的话,可对网络请求进行合并。