问题
我有一个带有请求模块的 NodeJS 服务器。我使用请求 pipe()
来提供文件。
有时,应用程序抛出异常,所有下载都取消,我必须重新启动应用程序:
内存不足:杀死进程9342(nodejs)得分793或牺牲孩子
杀死进程9342(nodejs)total-vm:1333552kB,anon-rss:410648kB,file-rss:0kB
我编写了另一个脚本,它在意外结束时自动重启服务器(使用 childprocess 和 fork),有时会引发此错误:
致命错误:CALL_AND_RETRY_2 分配失败 - 进程内存不足
服务器数据
内存:500MB(我知道这个不多,但很便宜)
Ubuntu 12.04.5 LTS
NodeJS 版本:v0.10.36
假设
- 并行下载过多
- 与 RAM 相关的管道有问题
关于1:
当有人下载一个大文件时,它的一部分会加载到RAM中(我对此一无所知,一次说20MB,如果我错了,请纠正我)。当 400MB 可用并且以相同的下载速度进行 20 次当前下载时,服务器崩溃,因为他不能一次在 RAM 中加载超过 400MB。
关于 2:
除了pipe()
我使用以下代码来跟踪当前和取消的下载:
req.on("close", function() {
currentDownloads--;
});
pipe()
没有正确关闭,并且它使用的 RAM 没有被清除。
问题
如果我的任何假设都是正确的,我该如何解决?如果不是,那可能是什么原因,或者更确切地说可能是什么原因(它是 NodeJS/请求模块/我的代码是错误还是错误,有没有更好的方法)?
完整代码
var currentDownloads = 0;
app.post("/", function (req, res) {
var open = false;
req.on("close", function () {
if (open) {
currentDownloads--;
open = false;
}
});
request.get(url)
.on("error", function (err) {
log("err " + err);
if (open) {
currentDownloads--;
open = false;
}
})
.on("response", function () {
open = true;
currentDownloads++;
})
.pipe(res);
});