fsnotify 与 too many open files

fsnotify

fsnotify 是用来监听文件、目录变化的一个 golang 开源库

在 Linux 系统使用中,遇到了too many open files问题

首次尝试

通常,有 2 处配置太小,会触发too many open files错误:

  • /etc/sysctl.conf文件中的fs.file-max
  • /etc/security/limits.conf文件中的hard nofilehard nofile

因此,更改了相关值:

[root@qa5 ~]# ulimit -a | grep open
open files                      (-n) 1024000

结果,还是出现too many open files问题

再次尝试

看官方文档,搜索到 README 中,也提到:

How many files can be watched at once?
There are OS-specific limits as to how many watches can be created:
Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a “no space left on device” error.
BSD / OSX: sysctl variables “kern.maxfiles” and “kern.maxfilesperproc”, reaching these limits results in a “too many open files” error.

因此,怀疑 max_user_watches 相关配置有问题

[root@qa5 ~]# sysctl fs.inotify
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192

fs.inotify.max_user_instances 只有 128 ,而这里使用的场景会开很多服务进程,每个服务都会 watch file

进程数也远超 128

修改 fs.inotify.max_user_instances 值,too many open files问题解除

检查 inotify 数量的工具

获取别人写的 shell 脚本

wget https://github.com/fatso83/dotfiles/blob/master/utils/scripts/inotify-consumers
chmod +x inotify-consumers

执行:

[root@qa5 ~]# ./inotify-consumers

   INOTIFY
   WATCHES
    COUNT     PID USER     COMMAND
--------------------------------------
       9      1 root     /usr/lib/systemd/systemd --switched-root --system --deserialize 22
       9   1186 root     /usr/sbin/NetworkManager --no-daemon
       8    869 root     /usr/lib/systemd/systemd-udevd
       7   1195 polkitd  /usr/lib/polkit-1/polkitd --no-debug
       3   1209 root     /usr/sbin/crond -n
       2   1620 root     /usr/sbin/rsyslogd -n
       2   1145 dbus     /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

      40  WATCHES TOTAL COUNT

40 WATCHES TOTAL COUNT的意思是,当前共有 40 个在监听文件变动

参考文档

其他问题

在增大open files 限制时,还遇到 docker 启动失败的问题:

Sep 22 13:16:57 qa5.haidao systemd[1]: Stopped containerd container runtime.
-- Subject: Unit containerd.service has finished shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit containerd.service has finished shutting down.
Sep 22 13:16:57 qa5.haidao systemd[1]: Starting containerd container runtime...
-- Subject: Unit containerd.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit containerd.service has begun starting up.
Sep 22 13:16:57 qa5.haidao systemd[8690]: Failed at step LIMITS spawning /sbin/modprobe: Operation not permitted
-- Subject: Process /sbin/modprobe could not be executed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- The process /sbin/modprobe could not be executed and failed.
--
-- The error number returned by this process is 1.
Sep 22 13:16:57 qa5.haidao systemd[8699]: Failed at step LIMITS spawning /usr/bin/containerd: Operation not permitted
-- Subject: Process /usr/bin/containerd could not be executed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- The process /usr/bin/containerd could not be executed and failed.
--
-- The error number returned by this process is 1.
Sep 22 13:16:57 qa5.haidao systemd[1]: containerd.service: main process exited, code=exited, status=205/LIMITS
Sep 22 13:16:57 qa5.haidao systemd[1]: Failed to start containerd container runtime.
-- Subject: Unit containerd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit containerd.service has failed.
--
-- The result is failed.
Sep 22 13:16:57 qa5.haidao systemd[1]: Dependency failed for Docker Application Container Engine.
-- Subject: Unit docker.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit docker.service has failed.
--
-- The result is dependency.
Sep 22 13:16:57 qa5.haidao systemd[1]: Job docker.service/start failed with result 'dependency'.
Sep 22 13:16:57 qa5.haidao systemd[1]: Unit containerd.service entered failed state.
Sep 22 13:16:57 qa5.haidao systemd[1]: containerd.service failed.
Sep 22 13:16:57 qa5.haidao polkitd[1163]: Unregistered Authentication Agent for unix-process:8667:522314 (system bus name :1.393, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus)

原因是,docker serivce 配置 /usr/lib/systemd/system/docker.serviceLimitNOFILE=infinity
/etc/sysctl.conf 中配置了 fs.nr_open=10240000 冲突
删除fs.nr_open=10240000 并执行:

sysctl -p --system

再重启 docker

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要解决"too many open files"的问题,可以从两个方面入手:修改系统配置和从程序层面解决。 首先,我们可以尝试修改系统的配置信息。根据引用所述,Linux系统维护了一个open files table来记录当前打开的文件信息,这个表有一个最大容量限制。如果超过这个限制,系统会拒绝其他文件操作并报错"Too many open files"。因此,我们可以通过修改系统配置来增加open files table的容量。 具体来说,可以通过修改Linux系统的文件描述符限制来提高open files table的容量。可以使用命令ulimit来查看和修改文件描述符限制。首先,使用ulimit -n命令查看当前文件描述符的限制。然后,根据实际需求,可以使用ulimit -n <new_limit>命令将文件描述符限制设置为一个较大的值。 除了修改系统配置,我们还可以从程序层面解决这个问题。引用提到,要复现这个问题通常需要一定的业务量和运行一段时间,才能达到系统的阈值。因此,我们可以通过优化程序的资源管理来避免打开过多的文件。 可以尝试以下几种方法来解决这个问题: 1. 确保在程序中正确关闭所有打开的文件。在程序运行结束或不再需要打开的文件时,及时关闭文件。 2. 使用文件池或缓存来管理文件的打开和关闭。通过维护一个固定大小的文件池,在需要访问文件时,从池中获取可用的文件句柄,使用完毕后将文件句柄放回池中。 3. 优化程序的资源使用。检查程序中是否存在资源泄漏或重复打开文件的情况,及时释放不再使用的资源。 综上所述,要解决"too many open files"的问题,可以通过修改系统配置来增加open files table的容量,以及从程序层面优化资源管理来避免打开过多的文件。这样可以提高系统的稳定性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值