如何在不修改ulimit的情况下处理nodejs EMFILE异常?

时间:2011-06-26 19:23:17

标签: asynchronous node.js

我是Node.JS的新手,我遇到了EMFILE错误。我正在捕捉EMFILE异常并在代码中处理它。

似乎有很多关于“错误:EMFILE,太多打开文件”错误的问题,但大多数答案似乎都是“增加你的ulimit”。

我的第一个问题是,如何捕获此异常?当我使用许多连接运行以下代码时,它会引发EMFILE错误:

  stream = net.createConnection(port, host);

  stream.addListener('connect', function() {
    return stream.write(request);
  });
  stream.addListener('data', function(data) {
    return console.log(data);
  });
  stream.addListener('end', function() {
    stream.end();
    return callback();
  });
  stream.addListener('timeout', function() {
    stream.destroy();
    console.log("timeout");
    return callback();
  });
  stream.addListener('error', function(e) {
    console.log("this never gets called");
    return
  });

异常没有被'错误'监听器捕获。我试图在try{} catch (e) {}中包含上述内容,但没有任何反应。我已经为createConnection使用了一个回调方法,它不会返回任何错误。

我能够捕获异常的唯一方法是:

process.on('uncaughtException', function(err) {
  console.log(err);
});

这似乎不安全,因为它抓住了一切。

所以我的第二个问题是:捕获错误并重试呼叫的“最佳实践”方法是什么?

我看过: https://github.com/isaacs/npm/blob/master/lib/utils/graceful-fs.jsSimple nodejs http proxy fails with "too many open files" 作为参考,但我不确定如何将 graceful 方法从npm应用到createConnection调用。

非常感谢!

1 个答案:

答案 0 :(得分:3)

即使你能抓住这个例外,你会对它有什么用处吗?如果你在某个地方有泄漏,你需要修复泄漏,如果你有正常但非常高的负载,那么你需要以某种方式处理它。无论哪种方式,当你遇到这种情况时,节点过程中的事情都很糟糕。

不幸的是,当您处理uncaughtException事件时,唯一安全的做法是记录错误消息然后退出该进程。抛出异常的堆栈现在已经消失,很可能很快就会产生内部混乱。

最佳解决方案是增加流程可用的文件描述符数量。好消息是文件描述符非常便宜。