Node.js 中的“连接 EMFILE”错误

Posted

技术标签:

【中文标题】Node.js 中的“连接 EMFILE”错误【英文标题】:"connect EMFILE" error in Node.js 【发布时间】:2012-05-08 11:44:23 【问题描述】:

我最近收到了大量运行 Node.js 的网站的流量。随着交通量的增加,它开始出现很多崩溃,这是以前从未发生过的。我的日志中出现以下错误:

 [Error: connect EMFILE] code: 'EMFILE', errno: 'EMFILE', syscall: 'connect' 
Error: connect EMFILE
    at errnoException (net.js:670:11)
    at connect (net.js:548:19)
    at net.js:607:9
    at Array.0 (dns.js:88:18)
    at EventEmitter._tickCallback (node.js:192:40)

有人知道它为什么会崩溃吗?以及如何解决它的想法?

我正在使用 Express.js 和 Socket.io。它在 Ubuntu 上运行。

【问题讨论】:

EMFILE 错误表示操作系统拒绝您的程序打开更多文件/套接字,请查看:***.com/q/34588/511300 谢谢斯图尔!更改 ulimit 解决了它。 不客气!添加它作为答案,所以你可以accept它。 我想说,这个问答绝对值得MORE 次观看,甚至与Hello World 一样多。开发人员按需打开并发套接字without any limitation,然而,他们不知道这意味着允许大量打开套接字的请求会导致他们的应用程序崩溃并搞砸所有事情。 没有警告,即使它可能是一个严重的漏洞。 在学习如何使用 forever 之前,必须告知开发人员 为了防止您的应用程序因大量连接而崩溃,首先,确定没有资源泄漏——您的应用程序不建立和保持不必要的连接;其次,选择limit your available concurrent sockets 或increase the OS's opened-socket limit。 【参考方案1】:

EMFILE 表示error maximum files,表示操作系统拒绝您的程序打开更多文件描述符。

注意系统中打开的文件包括磁盘文件、命名管道、网络套接字和所有进程打开的设备。

您的操作系统指定每个进程的打开文件限制。

要检查系统的打开文件限制,请使用ulimit -a 命令。一般在类 unix 系统上默认为 1024。

如果限制为 1024,则意味着您/进程最多可以打开 1024 个文件。如果超过此限制,则意味着openpipedup 系统调用将失败并产生 EMFILE 错误。

当您收到EMFILE 时,它主要表示您的代码中存在泄漏。如果您的程序出现泄漏,将 ulimit 增加到更高的值并不是一个好的解决方案。

您应该尝试找出泄漏的原因。以下可用于在 unix 等操作系统中进行调试:

    lsof 意思是list open files 命令给出打开文件的列表。假设您的 nodeJS 程序有泄漏,以便找出您的程序打开的文件描述符的总数:

    lsof | grep 节点 | wc -l

    要找出套接字的文件描述符,请使用:

    lsof -n -i -P | grep 节点

使用这个我们可以找出泄漏的位置,然后我们可以纠正它。

【讨论】:

【参考方案2】:

在我的例子中,我们已经设置了最高的 ulimit 集和 kern.maxfiles 配置,它可以在 Mac 上运行。

解决的问题是全局限制最大套接字数。在更高版本的节点中,限制是无限的。

尝试添加这些代码行:

var https = require('https');
var http = require('http');

https.globalAgent.maxSockets = 5;
http.globalAgent.maxSockets = 5;

在使用请求库的情况下,可以配置这些设置。

见:https://github.com/request/request#request---simplified-http-client

这里有更多关于 maxSockets 的信息:https://nodejs.org/api/http.html#http_agent_maxsockets

【讨论】:

【参考方案3】:

EMFILE 错误表示操作系统拒绝您的程序打开更多文件/套接字。

看看:How do I change the number of open files limit in Linux?

【讨论】:

增加你的套接字限制并不能修复泄漏,它只会让你的应用程序在一段时间内不会崩溃。 @jpillora 你有什么建议来防止泄漏?我有完全相同的问题,我不想通过增加 ulimit 来解决它,因为正如你所写,它是临时修复的。 @Robert 有时增加 ulimit 实际上是解决方案,比如如果它是 256 并且您的流量很高,虽然我是我的情况,但我反复打开文件流并且从不关闭它们,我抓住了此泄漏与 lsof -p 。如果失败了,你可以使用 izaacs graceful-fs 模块 不幸的是,graceful-fs 模块不适合我。由于套接字,我达到了限制,而不是因为使用 fs 打开了很多文件,但感谢您的帮助。 sockets和files都是文件描述符,ulimit修改文件描述符限制

以上是关于Node.js 中的“连接 EMFILE”错误的主要内容,如果未能解决你的问题,请参考以下文章

Node.js https pem 错误:routines:PEM_read_bio:no start line

Node.JS 错误 - process.env.NODE_TLS_REJECT_UNAUTHORIZED。这是啥意思?

Node.Js 错误“请求中不存在 'Access-Control-Allow-Origin' 标头”

Heroku 中的部署 React/Node 应用程序失败

Node.js权威指南 (10) - Node.js中的错误处理与断言处理

Node.js、discord.js 和 MySQL - ER_NO_SUCH_TABLE:表 'NAME' 不存在