错误代码 24:打开文件过多。但是我没有打开文件?

16

我正在使用treq (https://github.com/twisted/treq) 来从我的web服务查询其他api。今天我对自己的服务进行压力测试时,出现了以下错误:

twisted.internet.error.DNSLookupError: DNS查找失败:地址'api.abc.com'未找到:[Errno 24] 打开文件太多。

但问题是,在我的整个代码中,我没有打开任何文件。我怀疑是我查询的api崩溃或者被阻止(api.abc.com),因为我的压力测试可能像ddos一样攻击该终点。即使是这种情况,也不应该有拒绝连接之类的错误吗?我不知道为什么会出现 “Too many open files” 错误。或者是由于创建了太多线程查询造成的吗?


1
“files” 的确是指文件描述符,包括诸如套接字之类的内容,因此如果您打开了大量连接,则仍可能遇到此问题。 - Eric Renouf
2个回答

34

"文件"包括网络套接字,在基于Unix的系统上,它们是一种文件类型。最大打开文件数可通过 ulimit -n 进行配置,并且该限制会被子进程继承:

# 检查当前限制
$ ulimit -n
256
# 将限制提高到 2048 # 仅影响从此 shell 启动的进程 $ ulimit -n 2048 $ ulimit -n 2048

如果用尽了文件句柄并不足为奇,并且必须提高限制。但是,如果限制已经很高,您可能会泄漏文件句柄(未能快速关闭它们)。在诸如Python之类的垃圾收集语言中,终结器并不总是足够快地关闭文件,这就是为什么您应该小心使用 with 块或其他系统以便在完成后立即关闭文件。


看起来 ulimit 是特定于特定终端的。是这样吗?我的 ulimit 是 1024。我在一个终端中将其设置为 5000,但除了我设置为 5000 的终端之外,所有其他终端仍显示为 1024。 - phanny
2
@phanny:资源限制从父进程继承。 - Dietrich Epp
请问能否将Dietrich的评论添加到答案中呢? - Anatoly Alekseev

8

我想在Dietrich Epp的答案上进行补充。设置ulimit -n仅会更改当前终端的限制。如果您希望更改此限制,以便它适用于所有终端会话(例如在EC2上),则需要编辑:

vim /etc/security/limits.conf

并为每个用户打开描述符的软限制和硬限制添加限制。例如,您可以将此片段粘贴到上述文件中:

*         hard    nofile      500000
*         soft    nofile      500000
root      hard    nofile      500000
root      soft    nofile      500000

这将在每个新的终端会话中将限制设置为500000。编辑后,退出并重新登录(或者如果可以的话,重新启动),之后,您可以运行ulimit -n来确认已正确设置。


1
为什么默认值这么低?将ulimit设置为高值是否有任何缺点? - wsdzbm
1
@ddzzbbwwmm 说实话,这取决于你的应用程序是什么。有些应用程序依赖于大量打开的连接才能完成任务,而大多数任务在默认情况下都可以正常运行。将ulimit设置为较高值的缺点是它可能掩盖本来可以被发现的问题,例如使用大量资源的流氓进程。它充当一种保护措施。只要你了解你的应用程序并且能够监控事物,它就可以成为一个有用的设置。 - dave4jr

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