zoukankan      html  css  js  c++  java
  • [原创] 项目 watch EMFILE 报错处理过程

    事件

    公司XX游戏 S114服启动失败(使用 pomelo - node.js 框架的项目), 提示 : Caught exception: Error: watch EMFILE

    处理过程

    1. 怀疑是 "单进程可打开的最大文件句柄数" 受限

      # 查看单个任务最多可同时打开的文件数
      ulimit -n	# 65535
      

      查看各进程打开的文件句柄数

      lsof -n|awk '{print $3}'|sort|uniq -c|sort -nr
      

      输出结果:

          228 18942	# mysqld
          125 1450	
           89 29749	# 以下皆是游戏进程
           77 23603
           73 29183
           71 6912
           71 31880
           71 28674
           71 28059
           71 27888
           70 6899
           70 3212
           70 31866
           70 3083
           70 29741
           ...
      

      当前服务器已经启动多个项目实例, 唯独在启动当前这个新的实例时才报错。上面的输出结果显示, 游戏的每个进程打开的文件句柄数也才 80 左右,不可能达到上限。

    2. inotify 限制?

      查看当前inotify限制:

      [root@vm10-140-85-116 ~]# sysctl -a | grep fs.inotify
      fs.inotify.max_user_instances = 128
      fs.inotify.max_user_watches = 8192
      fs.inotify.max_queued_events = 16384
      

      百度了一下,项目使用 pomelo,”reloadHandlers会监听handler文件的修改,导致了这个fs.watch这个问题“

      inotify 是linux的文件系统时间监控机制。

      在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制

      • max_user_watches:设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
      • max_user_instances:设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
      • max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。

      尝试临时修改该参数配置:

      echo 256 > /proc/sys/fs/inotify/max_user_instances
      

      再次启动游戏服务端, OJBK 了, 确认没问题, 将上述修改的参数持久化(不然重启一下服务器又得重设)

      echo "fs.inotify.max_user_instance=256" >> /etc/sysctl.conf
      

    总结

    这个问题在于, 开启过多的 pomelo 实例,导致用户(pomelo进程所属)运行的 inotify 命令数超过默认的阀值,而非单个pomelo进程打开的文件句柄数超过限制。

    参考资料

    小知识点

    单进程文件句柄限制

    Linux 是有文件句柄限制的, 默认不高, 一般是 1024。作为生产环境的话很容易超出这个数值,因此大多数时候都需要调高该限制数。

    文件句柄数限制是针对:

    1. 针对单个进程的限制
    2. 修改该值时不影响当前运行中的程序

    查看当前句柄数限制ulimit -n

    1. 临时修改句柄数限制 (仅当前Session有效): ulimit -n 65535

      此处设置文件句柄数限制为 65535

    2. 写入配置文件 (永久生效)
      vim /etc/security/limits.conf
      末尾追加/修改

      *	hard	nofile	65535
      *	soft	nofile	65535
      

      hard 是硬限制,即实际限制 ;soft 是软限制,即warning

    分析句柄数

    (1)统计各进程打开句柄数:lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr

    (2)统计各用户打开句柄数:lsof -n|awk '{print $3}'|sort|uniq -c|sort -nr

    (3)统计各命令打开句柄数:lsof -n|awk '{print $1}'|sort|uniq -c|sort -nr

    系统总文件句柄限制

    除了对单进程可打开的文件句柄数量限制外, linux还会对系统级别的能够打开的文件句柄的数量进行限制, 即是对整个系统的限制, 而非针对单用户或单进程.

    查看当前系统级别能够打开的文件句柄数量:

    cat /proc/sys/fs/file-max	# 794168 Centos7 的默认值
    

    系统级打开最大文件句柄的数量永久生效的修改方法:

    1. /etc/sysctl.conf 文件末尾追加 fs.file-max = 2000000
    2. 执行 sysctl -p ,使修改配置立即生效

    sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下

    -w 临时改变某个指定参数的值

    -p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf中加载

    查看系统已分配句柄数: cat /proc/sys/fs/file-nr

    已分配文件句柄的数目, 已分配但未使用的文件句柄的数目, 文件句柄的最大数目

    对于服务器,一般修改进程级的最大打开文件句柄数即可(系统默认1024,有点小)。一般不需要调整系统级的最大数。

    如果出现了达到系统级别最大限制时,也需要同步调整系统级的最大数的。

    inotify 文件系统事件监控

    inotify 是linux的文件系统时间监控机制。

    在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制

    • max_user_watches:设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
    • max_user_instances:设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
    • max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。

    如出现 "too many open files" 提示, 记得来确认下是否是该参数配置问题

    临时修改该参数配置:

    echo 256 > /proc/sys/fs/inotify/max_user_instances
    

    参数持久化

    echo "fs.inotify.max_user_instance=256" >> /etc/sysctl.conf
    sysctl -p
    
  • 相关阅读:
    web.config中httpRedirect
    时间复杂度O(n)与空间复杂度O(1)
    NserviceBus过期处理
    struts的生命周期
    myeclipse 更改字体
    研磨struts2地址
    jQuery 实现公告无缝滚动
    统计网站访问图形数据链接
    工作经常使用的SQL整理
    使IE6下PNG背景透明的七种方法
  • 原文地址:https://www.cnblogs.com/youjiaxing/p/10302485.html
Copyright © 2011-2022 走看看