我正在研究 node + socket.io 应用程序。到目前为止,一切都很顺利。最近我开始收到一些错误:
Error: accept EMFILE
和
warn error raised error listen eaddrinuse
搜索互联网让我想到了这个 stackoverflow 问题:Node.js SSL server freeze, high CPU, not crashed but no connections。Knskan3 在回答中写道:
每个套接字创建一个新的虚拟文件。
我检查了一下,看起来每个套接字都会发出动作:
io.sockets.in(roomName).emit('some_action', data);
创建新的虚拟文件。
现在,当我有每秒发出数据的非常动态的应用程序时,将有办法在很短的时间内在服务器上创建许多新文件,最后服务器将达到最大文件的限制(默认为 1024)。我可以增加限制,但我认为这不是解决方案,因为它确实会产生很多排放。我是在做错事还是发出真的那样工作?你建议如何解决这个问题?
编辑: 经过一些答案后,我粘贴了控制台显示的内容:
xxxx:~# ls -l /proc/11124/fd | wc -l
20
xxxx:~# ls -l /proc/11124/fd | wc -l
21
xxxx:~# ls -l /proc/11124/fd | wc -l
22
xxxx:~# ls -l /proc/11124/fd
lrwx------ 1 root root 64 08-23 08:21 0 -> socket:[7352977]
lrwx------ 1 root root 64 08-23 08:21 1 -> socket:[7352980]
lrwx------ 1 root root 64 08-23 08:23 10 -> socket:[7444235]
lrwx------ 1 root root 64 08-23 08:23 11 -> socket:[7444237]
lrwx------ 1 root root 64 08-23 08:23 12 -> socket:[7444239]
lrwx------ 1 root root 64 08-23 08:23 13 -> socket:[7444245]
lrwx------ 1 root root 64 08-23 08:23 14 -> socket:[7444243]
lrwx------ 1 root root 64 08-23 08:23 15 -> socket:[7444252]
lrwx------ 1 root root 64 08-23 08:23 16 -> socket:[7444250]
lrwx------ 1 root root 64 08-23 08:23 17 -> socket:[7444254]
lrwx------ 1 root root 64 08-23 08:23 18 -> socket:[7445919]
lrwx------ 1 root root 64 08-23 08:23 19 -> socket:[7446836]
lrwx------ 1 root root 64 08-23 08:21 2 -> socket:[7352982]
lrwx------ 1 root root 64 08-23 08:23 20 -> socket:[7447275]
lrwx------ 1 root root 64 08-23 08:21 3 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 08-23 08:21 4 -> anon_inode:[eventfd]
lr-x------ 1 root root 64 08-23 08:21 5 -> pipe:[7352986]
l-wx------ 1 root root 64 08-23 08:21 6 -> pipe:[7352986]
lrwx------ 1 root root 64 08-23 08:21 7 -> socket:[7352987]
lrwx------ 1 root root 64 08-23 08:23 8 -> socket:[7444231]
lrwx------ 1 root root 64 08-23 08:23 9 -> socket:[7444233]
在每个操作之后,我运行命令:(ls -l /proc/11124/fd | wc -l
就像在我粘贴链接的站点中告知的那样)并且它增加一。对我来说,它看起来无论如何都会创建文件。我在互联网上看到了许多类似的情况,并建议的解决方案是增加 ulimit 但这不是解决方案,而是临时修复。
EDIT2: 好的,我发现了问题。我在应用程序内存缓存中使用。当我不再需要它时,我没有关闭连接,因此许多发出操作导致与 memcache 创建新连接而不是关闭它。现在一切正常。