2011 年 4 月 18 日,星期一

为何使用 HTTP 流传输?

fxn 发布

Rails 3.1 将会支持 HTTP 流传输(也称为块响应),这篇文章将说明其中原理。

什么是 HTTP 流传输?

常规的动态 HTTP 响应需要一个 Content-Length 头。其时间线如下所示

HTTP request -> dynamic content generation -> HTTP response

这些是三个串行步骤,因为您通常需要生成内容才能知道其大小,因此填充响应的内容长度头。

HTTP 提供了一种替代方案,这套方案能够在生成数据时立即刷新数据,称为块传输编码。这就是我们最近提交的内容中称之为“流传输”的原因。

流传输的响应没有 Content-Length 头。相反,它们有一个 Transfer-Encoding 头,其值为“chunked”,还有一个主体,主体由一系列块组成,您将这些块写入套接字前加上其各自的大小。模数详情。

下面是一个从维基百科摘取的示例

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

25
This is the data in the first chunk

1C
and this is the second one

3
con
8
sequence
0

关键在于您可以在获得块后立即将其刷新到套接字,而无需等待生成整个内容。

在何时 Web 浏览器会提取资源?

在收到内容后,Web 浏览器会解析文档。当他们找到一个引用的资源时(例如图像、样式表或脚本),便会发起获取请求。这与文档被接收和处理的同时进行,无论内容是否分块。

浏览器对可以执行的并发请求数量有限制,一个是全局限制(一般为 +30),另一个是每个域的限制(现在一般为 4 或 6),但在这些限制内,获取资源的请求会在解析内容时发生。

现代客户端甚至不会像老客户端一样阻塞 JavaScript 文件,它们会实现扫描程序,这些程序会超前查找资源节点并请求获取资源。例如,这是 WebKit 的预加载扫描程序

琐事:在我调查此问题时,我偶然发现如果 MIME 类型不清楚(例如没有明确的字符集的“text/html”),那么网络浏览器会缓冲 1 KB 的数据,并且不会发起任何资源请求,以便能够窥探内容并进行有根据的猜测

那么流传输有什么好处?

流传输不会减少延迟,也不会减少生成动态响应所需的时间。但由于应用程序直接发送内容,而不等待渲染整个响应,因此客户端能够更早地请求资源。特别是,如果您刷新 HTML 文档的头部,**CSS 和 JavaScript 文件将并行获取**,而服务器正在生成内容。其结果就是页面加载得更快。

后续

流式处理目前仍然在 Rails 3.1 中进行优化,以后会发表另一篇文章,介绍如何在 Ruby on Rails 应用程序中进行实践。

感谢

Tony Gentilcore 提供了他的专业指导,Tony,非常感谢!此外,还要非常感谢 Browserscope 项目 提供的非常有用的表格。