我写了一个简单的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);
但是当我改为使用流的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);
我的问题是为什么第一个代码不起作用?
答案 0 :(得分:4)
我一直在处理Node中的大文件,并注意到加载数据的异步调用可以比http流中的写入调用快得多。这会导致服务器崩溃的瓶颈,因为它会耗尽所有未完成的写入请求(位于缓冲区中)。管道设计用于管理流,以便不会发生这种情况。
readable.pipe(destination,[options])#
destination Writable Stream写入数据的目标 options对象管道选项 end Boolean读取器结束时结束写入器。默认= true 此方法从可读流中提取所有数据,并将其写入提供的目标,自动管理流,以便目标不会被快速可读的流淹没。
答案 1 :(得分:3)
我们可以在不使用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);