排查 Too many open files
1 问题描述
开发环境发版平台报 Too many open files,重启后恢复正常。
同事第一时间想到 ESTABLISHED 和 TIME-WAIT 的 TCP,建议从 netstat 入手。
但发版平台只是个管理系统,没有这么大的量,于是从 lsof 层面看看文件句柄。
2 os限制了打开文件数?
Linux限制进程打开文件数默认是1024。
执行 ulimit -a 发现 open files 是 65530,正常情况下不至于打满。
也可以执行 ulimit -n 直接返回进程最大文件数。
3 打开了哪些文件?
执行 lsof 查看进程当前打开了哪些文件:
lsof -p 31224 > lsof.txt
3.1 FD 文件描述符
分析一下 FD:
cat lsof.txt | awk '{print $4}'| sort | uniq -c
统计 | FD | 说明 | 举例 |
---|---|---|---|
34 | mem | memory-mapped file | /usr/jdk1.8.0_51/jre/lib/rt.jar /lib64/librt-2.12.so |
5 | DEL | 被进程打开过后删除了 | /tmp/jar_cache4820710964158921039.tmp |
1 | cwd | current work dirctory | /usr/local/tomcat/deploy-ms6411 |
1 | rtd | root directory | / |
1 | txt | 程序代码,如应用程序二进制文件本身或共享库 | /usr/jdk1.8.0_51/bin/java |
1 | 0r | 处于只读模式 | /usr/local/tomcat/build-detail/25190 |
1 | 1w | 处于只写入模式 | /usr/local/tomcat/logs/finance-deploy-ms--dev/web.log |
1 | 4u | 处于读取/写入模式 | 172.22.145.126:48953->172.22.23.160:mysql (ESTABLISHED) |
注意,这儿的 0r 只是举例,后面还有 1r、2r、3r... ,最多的就是这种。
3.2 TYPE 文件类型
分析一下 TYPE:
cat lsof.txt | awk '{print $5}'| sort | uniq -c
统计 | TYPE | 说明 | 举例 |
---|---|---|---|
518 | REG | 文件 | /usr/local/tomcat/build-detail/25190 |
59 | IPv6 | IP套接字 | 172.22.145.126:40961->git.sui.work:http (CLOSE_WAIT) |
27 | FIFO | 先进先出队列 | pipe |
7 | CHR | 字符设备 | /dev/random |
2 | DIR | 目录 | /usr/local/tomcat/deploy-ms6411 |
2 | unix | UNIX域套接字 | socket |
1 | IPv4 | IP套接字 | *:avt-profile-2 (LISTEN) |
最多的是REG,其实就是客户端发过来的请求,一直在读这个名为 /usr/local/tomcat/build-detail/25190 的文件。
4 结论
用户在发版平台构建的时候,构建日志通过前端轮询,所以能看到大量重复的 build-detail。
不能牺牲前端看日志的体验,可以尝试改造为 websocket,让发版平台从 jenkins 获取构建日志后推送到前端。