zoukankan      html  css  js  c++  java
  • 【转载】一次「Too many open files」故障

    一次「Too many open files」故障

    昨天,项目的 ElasticSearch 服务挂了,我说的挂可不是进程没了,因为有 Supervisor 保护,而是服务不可用了。以前曾经出现过一次因为 ES_HEAP_SIZE 设置不当导致的服务不可用故障,于是我惯性的判断应该还是 ES_HEAP_SIZE 的问题,不过登录服务器后发现日志里显示大量的「Too many open files」错误信息。

    那么 ElasticSearch 设置的最大文件数到底是多少呢?可以通过 proc 确认:

    shell> cat /proc/<PID>/limits

    结果是「4096」,我们还可以进一步看看 ElasticSearch 打开的都是什么东西:

    shell> ls /proc/<PID>/fd

    问题看上去非常简单,只要加大相应的配置项应该就可以了。此配置在 ElasticSearch 里叫做 MAX_OPEN_FILES,可惜配置后发现无效。

    按我的经验,通常此类问题多半是由于操作系统限制所致,可是检查结果一切正常:

    shell> cat /etc/security/limits.conf
    
    * soft nofile 65535
    * hard nofile 65535

    问题进入了死胡同,于是我开始尝试找一些奇技淫巧看看能不能先尽快缓解一下,我搜索到 @-神仙- 的一篇文章:动态修改运行中进程的 rlimit,里面介绍了如何动态修改阈值的方法,虽然我测试时都显示成功了,可惜 ElasticSearch 还是不能正常工作:

    shell> echo -n 'Max open files=65535:65535' > /proc/<PID>/limits

    此外,我还检查了系统内核参数 fs.file-nr 及 fs.file-max,总之一切和文件有关的参数都查了,甚至在启动脚本里硬编码「ulimit -n 65535」,但一切努力都显得毫无意义。

    正当山穷水尽疑无路的时候,同事一语道破玄机:关闭 Supervisor 的进程管理机制,改用手动方式启动 ElasticSearch 进程试试看。结果一切恢复正常。

    为什么会这样呢?因为使用 Supervisor 的进程管理机制,它会作为父进程 FORK 出子进程,也就是 ElasticSearch 进程,鉴于父子关系,子进程允许打开的最大文件数不能超过父进程的阈值限制,但是 Supervisor 中 minfds 指令缺省设置的允许打开的最大文件数过小,进而导致 ElasticSearch 进程出现故障。

    此故障原因本来非常简单,但我却陷入了经验主义的固定思维,值得反思。

    此条目由老王发表在Technical分类目录,并贴了标签。将固定链接加入收藏夹。

    《一次「TOO MANY OPEN FILES」故障》上有10个想法

      1. detailyang在2015-08-02 22:49:04说道:

        我们这边是superivsord的启动脚本里加上参数解决类似的问题
        ulimit -f unlimited
        ulimit -t unlimited
        ulimit -v unlimited
        ulimit -n 640000
        ulimit -m unlimited
        ulimit -u 320000

      2. 侯星辉在2015-08-03 13:37:09说道:

        我们也遇到过楼住类似的问题. 一次supervisor下面托管的服务 日志一直报错Too many open files . 查看该服务的系统limit 发现是设置了1024,而统计现在需要用到3000多个.

        https://attachments.tower.im/tower/f528b22a4e7747f383036688d5a9aa09?version=auto&filename=Clipboard%20Image.png
        解决思路两个出发点,
        1。是修改supervisor 启动脚本里加上 楼上的参数
        2。是修改了系统的/etc/security/limits.d/90-nproc.conf 文件 这个优先于/etc/security/limits.conf
        几个工程师再三考虑和分析之后 觉得还是第一种方案 更合适我们些.

      3. 包括daemontools(supervise)也是这样,这类服务管理工具的解决方法就是在运行的脚本最上面加上ulimit -n xxx

      4. Terry在2015-08-26 16:26:07说道:

        Oops, 竟然是 @轩脉刃 的同事, 看过好多@轩脉刃 大大的博文. Supervisor也在用, 目前尚未入坑, 先受教了, 谢谢.

      5. 你网站很好,能友链链接吗?回龙观空调加氟http://www.okhongkang.com 联系qq1715-658817

      6.  多谢了,刚好用上。跟楼主的情况一模一样,只是守护的服务不同。
      7. Pingback引用通告: Elasticsearch 索引小优化 | Wislay

      8. Pingback引用通告: Elasticsearch 索引小优化 | Nginlion

      9. huazai在2018-11-14 11:23:38说道:

        其实可以把要运行的command放到一个脚本里,然后在脚本里加ulimit限制

        #!/bin/bash

        ulimit -n xxxx

        #command
        ..

        然后把这个脚本放到supervisor里

      10. 涛涛在2019-01-10 17:21:57说道:

        这种问题我也遇到过 其实是因为supervisor 主进程没有继承系统的配置导致拿supervisor启动的服务limits都是默认的1024 如果条件允许的话 只需要重启supervisord 主进程即可解决

  • 相关阅读:
    零碎知识点
    安卓内存泄漏8种可能
    检测内存泄漏
    kotlin协程
    webview
    安卓各布局优缺点
    splice方法
    angular服务使用
    CSS3的一些笔记
    let、var、const
  • 原文地址:https://www.cnblogs.com/xuanbjut/p/11652981.html
Copyright © 2011-2022 走看看