事件

公司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

[原创] 项目 watch EMFILE 报错处理过程的更多相关文章

  1. ASP.NET MVC 复制MVC项目代码到同一个项目的时候报错The request for ‘home’ has found the following matching controll

    ASP.NET MVC 复制MVC项目代码到同一个项目的时候报错The request for ‘home’ has found the following matching controll “/” ...

  2. maven 项目启动tomcat报错 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

    maven项目启动tomcat报错: java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderLi ...

  3. iOS-C文件添加到iOS项目中,运行报错

    iOS-C文件添加到iOS项目中,运行报错 问题: 往项目中添加一个空的c文件, 编译运行; 出现2,30个编译错误. 原因: 由于在项目中添加了Pch文件,在文件中所有代码还没有开始运行之前, pc ...

  4. maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

    主要原因是maven项目里面的jar包吗,没有导入到项目中 maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframewor ...

  5. eclipse运行项目,tomcat报错:Exception in thread :http-bio-8080-exec-4

    eclipse运行项目,tomcat报错:Exception in thread :http-bio-8080-exec-4 转自 https://www.cnblogs.com/yby-blogs/ ...

  6. 导入项目的时候报错Error:Could not find com.android.support.constraint:constraint-layout:1.0.0-alpha7

    问题描述 今天在导入项目的时候报错: Error:Could not find com.android.support.constraint:constraint-layout:1.0.0-alpha ...

  7. 新建SpringBoot项目运行页面报错Whitelabel Error Page This application has no explicit mapping for /error, so yo

    新建SpringBoot项目运行页面报错Whitelabel Error Page This application has no explicit mapping for /error, so yo ...

  8. Eclipse的maven项目一直无故报错

    maven项目里面没报错,就是项目名称上有红色的叉叉,看着很不舒服: install都成功,但还是有红叉,刷新也没有用,最后搞了好一会才好: 操作步骤: 1.先把项目clean下: 选中要清理的项目, ...

  9. java项目连接jdbc报错:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server

    java项目连接jdbc报错:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not creat ...

随机推荐

  1. Zedboard学习(三):PL下流水灯实验 标签: fpgazynqPL 2017-07-05 11:09 21人阅读 评论(0)

    zynq系列FPGA分为PS部分和PL部分. PL: 可编程逻辑 (Progarmmable Logic), 就是FPGA部分. PS: 处理系统 (Processing System) , 就是与F ...

  2. 计蒜客D2T2 蒜头君的排序(动态维护树状数组)

    蒜头君的排序(sort) 2000ms 262144K 蒜头君是一个爱思考的好孩子,这一天他学习了冒泡排序,于是他就想,把一个乱序排列通过冒泡排序排至升序需要多少次交换,这当然难不倒他,于是他想来点刺 ...

  3. myeclipse如何将项目打包成war包

    打包步骤如下: 详细介绍请查看全文:https://cnblogs.com/qianzf/ 原文博客的链接地址:https://cnblogs.com/qzf/

  4. mysql user表 权限字段详解

    Select_priv.确定用户是否可以通过SELECT命令选择数据. Insert_priv.确定用户是否可以通过INSERT命令插入数据. Update_priv.确定用户是否可以通过UPDATE ...

  5. [GO]结构体指针类型匿名字段

    package main import "fmt" type Person struct { name string sex byte age int } type Student ...

  6. Spring框架总结(十二)

    问题引入:      程序的“事务控制”, 可以用aop实现! 即只需要写一次,运行时候动态植入到业务方法上. 一个业务的成功: 调用的service是执行成功的,意味着service中调用的所有的d ...

  7. msf、armitage

    msfconsole的命令: msfconsole use module :这个命令允许你开始配置所选择的模块. set optionname module :这个命令允许你为指定的模块配置不同的选项 ...

  8. Android 控件在布局中按比例放置[转]

    转自:http://netsky1990.blog.51cto.com/2220666/997452       在Android开发中常用到线性布局LinearLayout对界面进行具体的创建,其中 ...

  9. memcached整理の基本使用

    memcached 客户端与服务器端的通信比较简单,使用的基于文本的协议,而不是二进制协议.(http 协议也是这样), 因此我们通过telnet 即可与memcached 作交互. # 格式teln ...

  10. [转载].NET Web开发技术(补充)

    大家在工作应该养成善于总结的习惯,总结你所学习.使用的技术,总结你所工作事项的比较好的地方,善于总结不断的沉淀优化自己.适时停下来总结下过去走过的路,才能让我们的未来走的更坚定.文章转自JamesLi ...