商务合作加Q:411239339

后台程序出现Too-many-open-files是什么鬼?

浏览:538次阅读
没有评论

共计 2441 个字符,预计需要花费 7 分钟才能阅读完成。

后台程序出现 Too-many-open-files 是什么鬼?

-- 果较瘦 2020/01/16

一. 问题现象

打了一个小升级包,仅包含几个客户端 DLL 文件,然后用户设备中出现 haserver,AsmSvr 等模块状态为“STOP”的情况,系统运行不正常。

二. 问题分析

  1. 通过排查 haserver 和 AsmSvr 的日志发现,在服务不正常运行时,均打印出了 "Too many open files.." 的提示。
  2. 查看系统设置最大打开文件句柄数 ulimit -n,发现该值为 1000000
  3. 通过修改升级包 update.bat,增加一行打印来获取 ulimit - n 的值 %sshcmd% %ip% %username% %pass% "ulimit -a > /tmp/u.txt" %port% 发现 ulimit - n 值被修改成了 1024
  4. 进一步在 windows 命令行下手动执行命令,发现 depends\sshcmd.exe 目录下的程序报错

    后台程序出现 Too-many-open-files 是什么鬼?

  5. 查看程序代码发现传入的 sshcmd 命令行参数没有问题,通过查看做包工具源码发现,其真正用的 sshcmd.exe 在 depends 目录下的 AsmUpdate.bak 压缩包中
  6. 修改 AsmUpdate.bak 后缀为.rar,解压出来,使用其中的 sshcmd.exe 来执行

    后台程序出现 Too-many-open-files 是什么鬼?
    命令行下执行如下:
    后台程序出现 Too-many-open-files 是什么鬼?
    提示 All Done OK
    登录 172.22.112.9 后发现 /root 目录下并没有 ls.txt 文件,说明命令不生效。

  7. 从 svn co 源码下来,重新编译 ssh 命令,放入第 6 步中解压出来的目录后执行,可以生效,

    后台程序出现 Too-many-open-files 是什么鬼?
    查看 svn 提交记录,有可能上一位作者没有提交最新的 sshcmd.exe 命令至压缩包 AsmUpdate.bak 中,至此 sshcmd.exe 执行不生效的问题告一段落
    后台程序出现 Too-many-open-files 是什么鬼?

  8. 继续对比测试,直接将该命令放入升级包工具中执行,发现命令是生效的!!至此,不再纠结该问题。继续后续分析

三、寻找问题真相

  1. 为什么打个升级包会导致大量服务“异常停止”?

    通过解压升级包后发现,该升级包中勾选了“大版本升级包”选项,但没有勾选“要求重启设备”,该选项中会停止所有服务。在执行完升级后最后的升级脚本中会有一个 /asm/sh/asm.monitor 把未启动的服务拉起来。

  2. 为什么打升级包后,最大文件打开句柄数会变成 1024?

    通过查阅资料发现,远程执行命令与登录执行命令是有区别的
    后台程序出现 Too-many-open-files 是什么鬼?

  3. 为什么我通过 ssh 手动登录后查看 ulimit - n 文件句柄数是 1000000?
    ssh 手工登录时,默认会加载 /etc/profile 全局环境配置, 该配置中有一行命令 "ulimit -n 1000000",由于我们升级时使用的是 non-interactive 模式,使用的是 sysupdate 账户,此时查看 /home/sysupdate/.bashrc 文件,内容如下:
# .bashrc

# Source global definitions
if [-f /etc/bashrc]; then
        . /etc/bashrc
fi

# User specific aliases and functions

其中 /etc/bashrc 中有一段加载 /etc/profile.d/*.sh 的代码:

    # and interactive - otherwise just process them to set envvars
    for i in /etc/profile.d/*.sh; do
        if [-r "$i"]; then
            if ["$PS1"]; then
                . "$i"
            else
                . "$i" >/dev/null 2>&1
            fi
        fi
    done

    unset i
    unset pathmunge

这一段代码中与 /etc/profile 中加载的是同一段,再来了解一下登录环境变量加载行为:
根据登录加载环境变量顺序来看 /etc/profile -> /etc/profile.d/*.sh ->$HOME/.bashrc -> $HOME/.bash_profile

0x01 解决办法之一

目前系统中环境变量设置有两个地方我们进行了修改,一个是在 /etc/profile 末尾,一个是在 /etc/profile.d/asm.sh,而且在 /etc/profiles 中我们发现有一行设置:ulimit -n 1000000
那我们可以做如下操作:

整理我们在 /etc/profile 中添加的一段 asm 自定义环境变量设置至 /etc/profile.d/asm.sh 中,制作一个升级包,更新下 /etc/profile 和 /etc/profiles.d/asm.sh,问题得到解决

0x01 解决办法之二

从登录行为来解决:

  • ulimit 是 bash 内置命令,所以修改配置,不能立即生效,需要注销重新登录
  • 执行 ulimit 命令设置可以立即生效,但是仅仅针对当前会话生效
  • 本地登录和 ssh 远程登录不是一个会话,本地的修改不能体现在 ssh 远程登录上 (并不是本地配置没有生效)
  • /etc/ssh/sshd_config 中 UseLogin 默认是 no,更改为 yes 后,SSH 验证结束后会使用本地的 /bin/login 程序,会读取 /etc/security/limits.conf,所以 ulimit -a 的结果和本地登录看到的一致;

对比测试用例:

  • 测试步骤:
    步骤 A:Windows 远程执行命令 2 - 3 次:ssh.exe "172.22.112.9" "ASMUPDATE" "enc____888888" "ulimit -a > /root/ls.txt" 22 使用 ssh 工具登录 172.22.112.9 查看
  1. 不对 UseLogin 作任何修改,执行步骤 A 预期结果:OPEN FILES (-N) 1024
  2. 修改 UseLogin 为 Yes,执行步骤 A 预期结果:OPEN FILES (-N) 1000000
  3. 重启 ASM 设备,执行步骤 A 预期结果:OPEN FILES (-N) 1000000
  • 实际结果:
  1. 符合预期结果
  2. 符合预期结果
  3. 符合预期结果

四、总结

  1. 来问题了并不可怕,可怕的是下次再出现同样的问题而依旧不知道原因。
  2. 重现问题现象能更好的理清问题发生的背景
  3. 好的测试用例和步骤对问题排查有很大帮助
  4. 来了问题不要慌,如果有点慌,重新看总结 1 2 3 步
正文完
扫码赞助
post-qrcode
 0
果子
版权声明:本站原创文章,由 果子 于2025-01-05发表,共计2441字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。