计算机网络 HTTP 管线化
01.最初通信方式
- HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP连接。
- 以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着 HTTP 的普及,文档中包含大量图片的情况多了起来。
- 客户端与服务器端要进行通信,TCP协议为了保证通信的准确性,会进行“三次握手”来保证信息传递的准确性,确认完之后才会进行HTTP请求和响应的传输,传输完之后服务器端发出终止信号FIN,断开TCP连接。针对复杂的页面,这样太频繁会造成资源的开销。
02.出现的问题
- 因为当年都是些很小的文本传输,所以这样也没有多大问题,但是,随着HTTP的普及,文档中包含大量图片的情况多了起来,问题也就产生了。
- 比如,使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。
03.解决的方式
- 解决方式
- 持久化链接
- 管线化
04.持久化链接
- 什么是持久化链接
- 为了解决上述TCP连接的问题,HTTP/1.1想出了持久连接的方法,持久连接就是只要任意一端没有明确提出断开连接,则保持TCP连接状态。
- 持久连接的好处:
- 减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
- 减少开销的那部分时间,使HTTP请求和响应能够更早的结束,因此Web页面显示速度也就相应提高了。
05.管线化
- 什么是管线化
- 持久连接使得多数请求以管线化方式发送称为可能。从前发送请求后需等待并受到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
- 管线化的好处
- 比如当请求一个包含10张图片的HTMLWeb页面,与挨个连接相比,用持久连接可以让请求更快,而管线化技术则比持久连接还要快。请求越多,时间差就越明显!
06.判断传输完成
- 在早期不支持持久连接的时候,其实是可以依靠连接断开来判定当前传输已经结束,大部分浏览器也是这么干的,但这并不是规范的操作。应该使用 Content-Length 这个头部,来指定当前传输的实体内容长度。
- 在保持持久连接的情况下,依赖 Content-Length 来确定数据发送完毕。
- Content-Length 在这里起到了一个响应实体已经发送结束的判断依据。这样的情况下,我们就要求 Content-Length 必须和内容实体的长度一致,如果不一致,就会出现各种问题。
- 如果 Content-Length 小于内容实体的长度,则会截断,反之则无法判定当前响应已经结束,会将请求持续挂起造成 Padding 状态。
- 在响应一个请求的时候,就需要知道它的内容实体的大小。但是在实际应用中,有些时候内容实体的长度并没有那么容易获得。例如内容实体来自网络文件、或者是动态生成的。这个时候如果依然想要提前获取到内容实体的长度,只能开一个足够大的 Buffer,等内容全部缓存好了再计算。
- 但这并不是一个好的方案,全部缓存到 Buffer 里,第一会消耗更多的内存,第二也会更耗时,让客户端等待过久。
- 此时就需要一个新的机制,不依赖 Content-Length 的值,来判定当前内容实体是否传输完成,此时就需要 Transfer-Encoding 这个头部来判定。