Node.js没有关闭fs.createReadStream()创建的文件

时间:2016-02-04 14:42:30

标签: javascript node.js fs

在我的服务器上,每次用户使用我们的服务时,我们都必须从服务器获取它们的JSON文件。我是通过在我自己的函数中使用fs.createReadStream()来实现的。

function getJSONFromServer(filepath, callback){
    var data = fs.createReadStream(filepath);
    data.on('error', function (error) {
        console.log("Caught", error);
        callback(undefined, error);
    });
    var jsonFile = "";
    data.on('data', function(chunk) {
        jsonFile += chunk;
    });
    data.on('end', function() {
        var jsonData = JSON.parse(jsonFile);
        callback(jsonData);
        data.destroy();
        data.close();
    });
}

这可以完成工作,但不会关闭与文件的连接。因此,在读取1024个文件(我的服务器上的限制)之后,Node.js将产生错误EMFILE, too many open files。然后我必须杀死我们的Node.js服务器,再次打开它,这将清除“打开文件”。

我检查lsof -i -n -P | grep nodejs打开的文件数量。它显示如下:

nodejs  13707     node   10u  IPv4 1163695      0t0  TCP 127.0.0.1:55643->127.0.0.1:27017 (ESTABLISHED)
nodejs  13707     node   11u  IPv4 1163697      0t0  TCP 127.0.0.1:55644->127.0.0.1:27017 (ESTABLISHED)

打开多个文件。

我尝试过使用graceful-fs。我尝试过调用stream.destroy()stream.close(),但我仍然遇到同样的问题。我的服务器本质上是一个滴答作响的定时炸弹,因为我们得到了一个沉重,稳定的用户流,并且在这么多用户连接之后它将停止工作。

此外,ulimit -n [open file amount]不起作用,即使这样也不行,这不是一个长期的解决方案,因为我希望我的文件连接关闭而不是无缘无故地打开。

我正在使用Node.js版本v0.10.25Ubuntu 15.04 (GNU/Linux 3.19.0-42-generic x86_64)以及graceful-fs的最新版本(如果有帮助的话)!

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:4)

This has got to be the stupidest mistake I've ever made. Regardless, here's the answer. I hope I can save someone from dealing with this error and almost ripping their hair out.

I was running my app with /a_bunch_of_stuff:/ and not nodejs. Turns out, if you do node, it will likely return a version that is very old, which was nodejs --version for me. v0.10.25 however was node --version. Obviously this massive jump in versions would fix some stuff, so I ran the app with v5.6.0 instead of node app.js and I haven't had the issue at all since. There are now only 6 open files, whereas before we had over 1000 with time.

Damn it feels good to have this off my chest.