节点和错误:EMFILE,打开的文件太多

几天以来,我一直在寻找错误的可行解决方案

Error: EMFILE, too many open files

似乎很多人都有同样的问题。通常的答案是增加文件描述符的数量。因此,我已经尝试过:

sysctl -w kern.maxfiles=20480

默认值为10240。在我眼中这有点奇怪,因为我在目录中处理的文件数在10240以下。甚至更陌生的是,在增加文件描述符的数量后,我仍然收到相同的错误。 。

第二个问题:

经过多次搜索,我发现解决了“打开文件过多”的问题:

var requestBatches = {};
function batchingReadFile(filename, callback) {
  // First check to see if there is already a batch
  if (requestBatches.hasOwnProperty(filename)) {
    requestBatches[filename].push(callback);
    return;
  }

  // Otherwise start a new one and make a real request
  var batch = requestBatches[filename] = [callback];
  FS.readFile(filename, onRealRead);

  // Flush out the batch on complete
  function onRealRead() {
    delete requestBatches[filename];
    for (var i = 0, l = batch.length; i < l; i++) {
      batch[i].apply(null, arguments);
    }
  }
}

function printFile(file){
    console.log(file);
}

dir = "/Users/xaver/Downloads/xaver/xxx/xxx/"

var files = fs.readdirSync(dir);

for (i in files){
    filename = dir + files[i];
    console.log(filename);
    batchingReadFile(filename, printFile);

不幸的是,我仍然收到相同的错误。此代码有什么问题?

最后一个问题(我是javascript和node的新手),我正在开发一个Web应用程序,该应用程序每天有大约5000个用户,并且有很多请求。我在使用其他语言(例如python和java)进行编程方面有多年的经验。所以最初我想用django或play框架开发此应用程序。然后,我发现了节点,我必须说,非阻塞I / O模型的想法真的很好,很诱人,而且最重要的是非常快!

但是,我应该对Node遇到什么样的问题?它是经过生产验证的Web服务器吗?你有什么经验?

番长猴子2020/03/26 16:46:54

对于nodemon用户:只需使用--ignore标志即可解决该问题。

例:

nodemon app.js --ignore node_modules/ --ignore data/
小卤蛋2020/03/26 16:46:54

用风笛,你只需要改变

FS.readFile(filename, onRealRead);

=>

var bagpipe = new Bagpipe(10);

bagpipe.push(FS.readFile, filename, onRealRead))

风笛可以帮助您限制平行度。更多详细信息:https : //github.com/JacksonTian/bagpipe

番长Jim2020/03/26 16:46:54

运行nodemon命令时遇到了同样的问题,所以我减少了以崇高的文字打开的文件名,并且错误消失了。

西里神奇2020/03/26 16:46:54

以@ blak3r的答案为基础,这是我使用的一些速记方式,以防其他诊断:

如果您要调试已耗尽文件描述符的Node.js脚本,则以下一行可以为您提供所涉及lsof的节点进程使用的输出

openFiles = child_process.execSync(`lsof -p ${process.pid}`);

这将由lsof当前正在运行的Node.js进程同步过滤运行,并通过缓冲区返回结果。

然后使用console.log(openFiles.toString())将缓冲区转换为字符串并记录结果。

飞云神无2020/03/26 16:46:54

使用graceful-fsIsaac Schlueter(node.js维护者)模块可能是最合适的解决方案。如果遇到EMFILE,它将执行增量回退。它可以用作内置fs模块的替代产品

西里神奇2020/03/26 16:46:54

我不确定这是否会帮助任何人,我开始从事具有很多依赖项的大项目,这使我犯了同样的错误。我的同事建议我watchman使用brew 安装,这为我解决了这个问题。

brew update
brew install watchman

在2019年6月26日编辑: Github到守望者的链接