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

2023-11-29

几天来我一直在寻找错误的有效解决方案

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

看来很多人都有同样的问题。通常的答案是增加文件描述符的数量。所以,我尝试过这个:

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);

不幸的是我仍然收到同样的错误。 这段代码有什么问题?


优雅的FS不起作用...或者您只是想了解泄漏来自哪里。遵循这个过程。

(例如,如果您的问题与套接字有关,则 Graceful-fs 不会修复您的马车。)

来自我的博客文章:http://www.blakerobertson.com/devlog/2014/1/11/how-to-define-whats-causing-error-connect-emfile-nodejs.html

如何隔离

此命令将输出 Nodejs 进程的打开句柄数:

lsof -i -n -P | grep nodejs
COMMAND     PID    USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
...
nodejs    12211    root 1012u  IPv4 151317015      0t0  TCP 10.101.42.209:40371->54.236.3.170:80 (ESTABLISHED)
nodejs    12211    root 1013u  IPv4 151279902      0t0  TCP 10.101.42.209:43656->54.236.3.172:80 (ESTABLISHED)
nodejs    12211    root 1014u  IPv4 151317016      0t0  TCP 10.101.42.209:34450->54.236.3.168:80 (ESTABLISHED)
nodejs    12211    root 1015u  IPv4 151289728      0t0  TCP 10.101.42.209:52691->54.236.3.173:80 (ESTABLISHED)
nodejs    12211    root 1016u  IPv4 151305607      0t0  TCP 10.101.42.209:47707->54.236.3.172:80 (ESTABLISHED)
nodejs    12211    root 1017u  IPv4 151289730      0t0  TCP 10.101.42.209:45423->54.236.3.171:80 (ESTABLISHED)
nodejs    12211    root 1018u  IPv4 151289731      0t0  TCP 10.101.42.209:36090->54.236.3.170:80 (ESTABLISHED)
nodejs    12211    root 1019u  IPv4 151314874      0t0  TCP 10.101.42.209:49176->54.236.3.172:80 (ESTABLISHED)
nodejs    12211    root 1020u  IPv4 151289768      0t0  TCP 10.101.42.209:45427->54.236.3.171:80 (ESTABLISHED)
nodejs    12211    root 1021u  IPv4 151289769      0t0  TCP 10.101.42.209:36094->54.236.3.170:80 (ESTABLISHED)
nodejs    12211    root 1022u  IPv4 151279903      0t0  TCP 10.101.42.209:43836->54.236.3.171:80 (ESTABLISHED)
nodejs    12211    root 1023u  IPv4 151281403      0t0  TCP 10.101.42.209:43930->54.236.3.172:80 (ESTABLISHED)
....

注意:1023u(最后一行)- 这是第 1024 个文件句柄,也是默认的最大值。

现在,看看最后一栏。这表明哪个资源是开放的。您可能会看到许多行都具有相同的资源名称。希望现在可以告诉您在代码中查找泄漏的位置。

如果您不知道多个节点进程,请首先查找哪个进程的 pid 为 12211。这会告诉您该进程。

在上面的例子中,我注意到有一堆非常相似的 IP 地址。他们都是54.236.3.###通过进行 IP 地址查找,在我的情况下能够确定它与 pubnub 相关。

命令参考

使用此语法来确定进程打开了多少个打开的句柄...

获取特定 pid 的打开文件计数

我使用此命令来测试在我的应用程序中执行各种事件后打开的文件数量。

lsof -i -n -P | grep "8465" | wc -l
# lsof -i -n -P | grep "nodejs.*8465" | wc -l
28
# lsof -i -n -P | grep "nodejs.*8465" | wc -l
31
# lsof -i -n -P | grep "nodejs.*8465" | wc -l
34

你的进程限制是多少?

ulimit -a

您想要的行将如下所示:

open files                      (-n) 1024

永久更改限制:

  • 在 Ubuntu 14.04、nodejs v.7.9 上测试

如果您希望打开许多连接(websockets 就是一个很好的例子),您可以永久增加限制:

  • 文件:/etc/pam.d/common-session(添加到最后)

      session required pam_limits.so
    
  • 文件:/etc/security/limits.conf(添加到末尾,如果已经存在则进行编辑)

      root soft  nofile 40000
      root hard  nofile 100000
    
  • 重新启动你的nodejs并从ssh注销/登录。

  • 这可能不适用于较旧的 NodeJS,您需要重新启动服务器

  • 如果您的节点使用不同的 uid 运行,请使用而不是。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐