too many open files linux服务器 golang java

zhangboyu · · 968 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1. 现象

服务的cpu跑满(golang实现), 并大量报too many open files错误.服务使用systemd来运行,部署在阿里ecs.

2.分析

从日志来看,cpu的上升主要为到达文件数限制引起的,但之前已经更改过系统的文件数及所有用户的文件数,按道理是不应该出现这个问题的,后来查阅资料发现,文件数可以从三个维度限制分别为操作系统限制,用户态限制,以及进程限制,对于这三个维度选取最小值生效.于是对系统进行分析.

首先查看当前打开文件数, 进程占用的文件数并不多.

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



然后获取系统级文件数限制

输入命令

cat /etc/sysctl.conf

得到

fs.file-max = 1000000

查询用户级文件数限制

cat /etc/security/limits.conf

得到

* soft nofile 655350

* hard nofile 655350

单独获取程序文件数限制(9928为进程id)

cat /proc/9928/limits

得到

Max open files            1024                 4096                 files    

如上可以发现, 虽然系统及用户的文件数调大了,但是程序的仍然是一个很低的值, 这里进程的文件数一般情况下是默认继承用户级的值的,而这里却没有继承,一开始怀疑是systemd启动的问题,但是手写了另外一个测试服务,发现该服务又继承了用户文件数.

百思不得其解的情况下在systemd的启动脚本里加了文件数的初始化值.

 如下:

[Service]

Type=simple

LimitNOFILE=40960

LimitNPROC=40960

  

单独获取程序(9928为进程id)

cat /proc/9928/limits

得到

Max open files            40960                 40960                 files    



发现文件数被设置成了启动时的初始化值.至于为什么没有继承用户级的值,怀疑是程序里做了参数设置,这里如果有人知道golang里具体情况的话,还望不吝赐教.

3. 总结

归结来说出现文件描述符的错误的排查步骤如下:

首先,判断配置参数是否正确,这里涉及到对上面提到的三个维度的检查,特别时进程维度的,如果只是ulimit -n 一下就完事了,那估计旧要像我一样进坑了.

如果参数都正确,那么查看一下当前系统被使用了多少文件数,如果使用的确实多,那要看一下使用在什么地方,这里一般有两种情况,大量连接未关闭,或者大量读文件的句柄未关闭.具体原因相信到这里就可以排查出来了.


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:zhangboyu

查看原文:too many open files linux服务器 golang java

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

968 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传