Node.js和Linux中的打开文件限制

3

我使用一个 node.js 客户端向我的服务器发送许多请求(服务器也是用 node.js 编写的)。

服务器收到了对特定文件的请求,并将其上传到 S3。

两分钟后,当所有事情都进行得很顺利时,我会收到以下错误:

{ [NetworkingError: getaddrinfo ENOTFOUND]
  message: 'getaddrinfo ENOTFOUND',
  code: 'NetworkingError',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  region: 'us-east-1',
  hostname: 'XXXX.s3.amazonaws.com',
  retryable: true,
  time: Sun Oct 12 2014 11:27:54 GMT-0400 (EDT),
  _willRetry: false }

经过我的一些小研究,我发现这个问题的出现可能是因为我尝试打开太多文件句柄或套接字,这只会在一段时间后才会真正发生。

但据我所知,node.js应该为我封装这个问题。换句话说,node.js应该了解文件描述符的限制,并根据这个限制打开一个新的文件描述符。这是使用基于事件的单用户线程的优势(我错了吗?)

如果node.js没有这样做,那么对于这个错误,什么是最好的解决方案,而不是增加我的打开文件限制(这是一个坏主意,因为我们需要这台机器上的良好性能。此外,如果我增加数量,如何确保这个错误不会再次出现?我怎么知道操作系统为此应该有多少个数?)


这并不是因为你达到了打开文件描述符的限制。如果是这样,你应该会看到 EMFILE 而不是 ENOTFOUNDENOTFOUND 表示无法找到该主机名的主机。请检查您的 DNS 服务器是否可以通过在运行您的节点脚本的系统上的 shell 提示符中执行类似于 ping XXXX.s3.amazonaws.com 的命令来解析该主机名。 - mscdex
也许在之前的请求中远程端点崩溃了?而且可能一些监控系统会在一段时间后自动重新启动它...?你应该一定要挖掘出你所拥有的任何服务器日志。 - Robert Rossmann
1个回答

3

在Ubuntu中,文件默认的打开描述符是1024。你可以使用终端设置ulimit -n。

ulimit -n   #a number

但是这将仅对当前登录会话进行更改。要使更改永久生效,请使用以下命令。
ulimit -n   #see the number of open files

sudo vi /etc/security/limits.conf    #open the file in vi

现在设置两者:

用户软限制nofile为9000

用户硬限制nofile为65000

root用户软限制nofile为9000

root用户硬限制nofile为65000

sudo vi /etc/pam.d/common-session

现在添加这一行:

session required pam_limits.so

http://posidev.com/blog/2009/06/04/set-ulimit-parameters-on-ubuntu/

编辑:

如果您不想改变ulimits而解决这个问题,则必须限制发出的请求总数少于当前的ulimit -n。

通过创建一个Http长连接池并开始将请求通过它们推送,或者限制从您的应用程序发出的最大并发请求数量,并将超过此限制的任何请求添加到队列中以便稍后处理。

这只是一个概念,如果您需要更多关于此问题的帮助,请向我们展示一些代码,这样我们就可以想象您正在尝试做什么。

希望这有所帮助。


您可能没有在随机云服务器提供商上执行这些操作的权限。此外,OP的问题暗示了问题所在,但似乎错误并不是由于打开太多文件引起的。 - Robert Rossmann
这是根据OP目前的问题正确的答案。操作系统文件限制就是操作系统文件限制。编程语言与此无关。 - slebetman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接