从节点http服务器下载大文件,服务器内存不足

我写了一个简单的http服务器,并下载一个大文件(1.5G),服务器因内存不足而崩溃

我的代码如下:

var http = require("http"); var fs = require("fs"); var filename = "file.iso"; var serv = http.createServer(function(req,res){ var stat = fs.statSync(filename); res.writeHeader(200,{"Content-Length":stat.size}); var fReadStream = fs.createReadStream(filename); fReadStream.on('data', function (chunk) { res.write(chunk); }); fReadStream.on('end', function () { res.end(); }); }); serv.listen(8888); 

但是当我改变使用stream的pipe方法,它确定,像这样:

 var http = require("http"); var fs = require("fs"); var filename = "file.iso"; var serv = http.createServer(function(req,res){ var stat = fs.statSync(filename); res.writeHeader(200,{"Content-Length":stat.size}); var fReadStream = fs.createReadStream(filename); fReadStream.pipe(res); }); serv.listen(8888); 

我的问题是为什么第一个代码不起作用?

我一直在使用Node中的大文件,并且注意到加载数据的asynchronous调用可以比httpstream中的写入调用更快地完成。 这会导致一个瓶颈,会导致服务器崩溃,因为所有未完成的写入请求(坐在缓冲区中)内存不足。 pipe道devise是为了pipe理stream,所以这不会发生。

从节点文档:

readable.pipe(目的地,[选项])#

目标可写入stream写入数据选项的目的地对象pipe道选项结束布尔当阅读器结束时结束写入程序。 默认值= true此方法将所有数据从可读stream中提取出来,并将其写入所提供的目标,自动pipe理stream,以便目标不会被快速可读的stream所淹没。

我们可以在没有pipe情况下平衡读写:

 var http = require("http"); var fs = require("fs"); var filename = "file.iso"; var serv = http.createServer(function (req, res) { var stat = fs.statSync(filename); res.writeHeader(200, {"Content-Length": stat.size}); var fReadStream = fs.createReadStream(filename); fReadStream.on('data', function (chunk) { if(!res.write(chunk)){ fReadStream.pause(); } }); fReadStream.on('end', function () { res.end(); }); res.on("drain", function () { fReadStream.resume(); }); }); serv.listen(8888);