如果我没弄错的话,我记得异步I / O(Node.js,Nginx)的“事件循环”模型不适合服务大文件。
是这种情况,如果是这样,周围有方法吗?我正在考虑在Node中编写一个实时文件浏览器/文件服务器,但文件可能在100MB到3GB之间。我会假设事件循环将阻塞,直到文件完全服务?
答案 0 :(得分:21)
不,它不会被阻止。 node.js将以块的形式读取文件,然后将这些块发送到客户端。在两个块之间,它将为其他请求提供服务。
阅读文件&通过网络发送数据是I / O绑定操作。 node.js将首先要求操作系统读取文件的一部分,而操作系统正在执行该节点.js将为另一个请求提供服务。当操作系统返回带有数据的node.js时,node.js将告诉操作系统将该数据发送到客户端。在发送数据时,node.js将为另一个请求提供服务。
亲自试试:
创建一个大文件
dd if=/dev/zero of=file.dat bs=1G count=1
运行此node.js app
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值。
答案 1 :(得分:2)
如果我没弄错,我记得异步的“事件循环”模型 I / O(Node.js,Nginx)不适合服务 大文件。
我认为你认为node.js没有针对提供大文件进行优化。我建议你去看看Ryan Dahl的slides。尤其
幻灯片14
哇。节点很糟糕,提供大型文件。超过3秒的回复 对于300个并发连接的256千字节文件。
幻灯片15
发生了什么:V8有一代分类垃圾收集器。移动 随机的物体。 Node无法获取指向原始字符串数据的指针 写入socket。
幻灯片21
但事实仍然是,将大字符串推入套接字的速度很慢。
希望将来可以减轻这种情况。
很有趣。也许这已经改变了,但我认为使用NGinx提供静态文件(或者CDN)可能会更好。我认为你错误地认为NGinx在提供大型文件时表现不佳。由于V8垃圾收集,Node.js对此不好,不是因为事件循环。 this link也可能很有趣。