大文件的事件循环?

如果我没有弄错,我记得asynchronousI / O(Node.js,Nginx)的“事件循环”模型不适合为大文件服务。

是这样的,如果是这样的话,有没有方法呢? 我正在考虑在Node中编写一个实时文件浏览器/文件服务器,但文件可能在100MB到3GB之间。 我会假设事件循环会阻塞,直到文件被完全服务?

不,它不会被阻止。 node.js将以块读取文件,然后将这些块发送给客户端。 在块之间它将服务其他请求。

通过networking读取文件和发送数据是I / O绑定操作。 node.js将首先要求操作系统读取文件的一部分,而操作系统正在执行该节点.js将服务于另一个请求。 当操作系统回到node.js中时,node.js会通知操作系统将这些数据发送给客户端。 在发送数据时,node.js将服务于另一个请求。

自己尝试一下:

创build一个大文件

dd if=/dev/zero of=file.dat bs=1G count=1

运行这个node.js应用程序

 var http = require('http'); var fs = require('fs'); var i = 1; http.createServer(function (request, response) { console.log('starting #' + i++); var stream = fs.createReadStream('file.dat', { bufferSize: 64 * 1024 }); stream.pipe(response); }).listen(8000); console.log('Server running at http://127.0.0.1:8000/'); 

请求http://127.0.0.1:8000/几次,看node.js处理它们。

如果您打算提供大量的大文件,您可能需要尝试不同的bufferSize值。

如果我没有弄错的话,我记得asynchronousI / O(Node.js,Nginx)的“事件循环”模型不适合为大文件服务。

我认为你的立场是正确的,node.js没有优化服务大文件。 我build议你看看Ryan Dahl的幻灯片 。 特别

幻灯片14

哇。 节点吸食大量文件。 在300个并发连接上对256千字节文件进行超过3秒的响应。

幻灯片15

发生了什么事情:V8有一代垃圾收集器。 随机移动物体。 节点无法获得指向原始string数据的指针以写入套接字。

幻灯片21

但事实仍然是,将大string推入套接字很慢。

希望这可以在未来减轻。

很有意思 也许这已经改变了,但是我认为使用NGinx来提供静态文件(或者CDN)可能会更好。 我认为你误以为NGinx在服务大文件方面不好。 由于V8的垃圾收集,Node.js在这方面不好,不是因为事件循环。 此链接也许是有趣的。