Too many open files 问题处理一例

向右看齐 2022-08-07 02:39 337阅读 0赞
  1. 今天同事在测试CentOS系统中进行程序测试时,遇到一个问题:
  2. 同事编写一个程序,配置在两台服务器上,一个作为服务器端,一个作为客户端,程序运行时,客户端会向服务器发起连接;
  3. 程序执行后,会打开5万多个文件,这时再次用一个其他客户端连接CentOS系统就会提示“Too many open files”错误而不能连接;
  4. 执行 losf | wc -l 命令查看当前系统所有的进程打开文件数时,显示为 51000
  5. 执行 ulimit -a 命令查看当前系统的所有用户限制时,发现其中的“open files”限制为 51200,这时程序打开的文件数基本上已经达到了open files的限制,所以再有会话数连接到系统,就会由于不能打开新的文件而提示错误;
  6. 于是将用户打开文件数限制调大, 修改/ect/security/limits.conf,添加如下信息:

* soft nofile 512000

* hard nofile 512000

  1. 使用 reboot 命令重启系统,使参数配置生效,然后使用 ulimit -a 命令查看,open files限制已经修改为 512000 了。
  2. 再次启动程序,打开了5万多会话数后,使用一个客户端连接还是会提示“too many open files”错误而不能连接;
  3. 但是如果用一个root用户连接CentOS系统,是可以连接的,说明除了 ulimit 的用户限制外,还有其他的open files限制,造成了这种情况。
  4. 后来经过查询确认,open files限制有两种,上面修改的是用户级open files限制,还有系统级open files限制,使用下面命令查看:

# cat /proc/sys/fs/file-max
51200
# sysctl -a | grep fs.file-max
fs.file-max = 51200

  1. 原来虽然修改了 /etc/security/limit.conf 中的用户限制,但系统限制还是51200,所以文件打开数大了之后,新的会话还是不能连接。
  2. 于是采用下面的方面修改参数:

打开系统配置文件,vim /etc/sysctl.conf ,

将其中的“fs.file-max = 51200”

修改为“fs.file-max = 512000”

  1. 然后使用 sysctl -p 命令,通知系统改参数已经修改,确认系统级的open files参数也已经修改了。
  2. 再次打开程序验证,就没有再出现 too many open files”的错误,程序可以正常运行了。

**********************************

附:网上一则对“too many open files”问题进行说明的文章:

运行在Linux系统上的Java程序可能会出现”Too many open files”的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景。

  1. 程序经常访问的文件、socketLinux中都是文件file,系统需要记录每个当前访问filenamelocationaccess authority等相关信息,这样的一个实体被称为file entry。“open files table”(图中橙色标识)存储这些file entry,以数组的形式线性管理。文件描述符(file descriptor)作为进程到open files table的指针,也就是open files table的下标索引,将每个进程与它所访问的文件关联起来了。

![Image 1][] 20150227165813596

  1. 每个进程中都有一个file descriptor table管理当前进程所访问(open or create)的所有文件,文件描述符关联着open files table中文件的file entry。细节不表,对于open files table能容纳多少file entryLinux系统配置open files table的文件限制,如果超过配置值,就会拒绝其它文件操作的请求,并抛出Too many open files异常。这种限制有系统级和用户级之分。
  2. 系统级:
  3. 系统级设置对所有用户有效。可通过两种方式查看系统最大文件限制
  4. 1 cat /proc/sys/fs/file-max
  5. 2 sysctl -a 查看结果中fs.file-max这项的配置数量
  6. 如果需要增加配置数量就修改/etc/sysctl.conf文件,配置fs.file-max属性,如果属性不存在就添加。
  7. 配置完成后使用sysctl -p来通知系统启用这项配置
  8. 用户级:
  9. Linux限制每个登录用户的可连接文件数。可通过 ulimit -n来查看当前有效设置。如果想修改这个值就使用 ulimit -n <setting number> 命令。
  10. 对于文件描述符增加的比例,资料推荐是以2的幂次为参考。如当前文件描述符数量是1024,可增加到2048,如果不够,可设置到4096,依此类推。
  11. 在出现Too many open files问题后,首先得找出主要原因。最大的可能是打开的文件或是socket没有正常关闭。为了定位问题是否由Java进程引起,通过Java进程号查看当前进程占用文件描述符情况:

Java代码 ![复制代码][Image 1] ![收藏代码][Image 1]

  1. lsof -p $java_pid 每个文件描述符的具体属性
  2. lsof -p $java_pid | wc -l 当前Java进程file descriptor table中FD的总量
  1. 分析命令的结果,可判断问题是否由非正常释放资源所引起。
  2. 今天同事在测试CentOS系统中进行程序测试时,遇到一个问题:
  3. 同事编写一个程序,配置在两台服务器上,一个作为服务器端,一个作为客户端,程序运行时,客户端会向服务器发起连接;
  4. 程序执行后,会打开5万多个文件,这时再次用一个其他客户端连接CentOS系统就会提示“Too many open files”错误而不能连接;
  5. 执行 losf | wc -l 命令查看当前系统所有的进程打开文件数时,显示为 51000
  6. 执行 ulimit -a 命令查看当前系统的所有用户限制时,发现其中的“open files”限制为 51200,这时程序打开的文件数基本上已经达到了open files的限制,所以再有会话数连接到系统,就会由于不能打开新的文件而提示错误;
  7. 于是将用户打开文件数限制调大, 修改/ect/security/limits.conf,添加如下信息:

* soft nofile 512000

* hard nofile 512000

  1. 使用 reboot 命令重启系统,使参数配置生效,然后使用 ulimit -a 命令查看,open files限制已经修改为 512000 了。
  2. 再次启动程序,打开了5万多会话数后,使用一个客户端连接还是会提示“too many open files”错误而不能连接;
  3. 但是如果用一个root用户连接CentOS系统,是可以连接的,说明除了 ulimit 的用户限制外,还有其他的open files限制,造成了这种情况。
  4. 后来经过查询确认,open files限制有两种,上面修改的是用户级open files限制,还有系统级open files限制,使用下面命令查看:

# cat /proc/sys/fs/file-max
51200
# sysctl -a | grep fs.file-max
fs.file-max = 51200

  1. 原来虽然修改了 /etc/security/limit.conf 中的用户限制,但系统限制还是51200,所以文件打开数大了之后,新的会话还是不能连接。
  2. 于是采用下面的方面修改参数:

打开系统配置文件,vim /etc/sysctl.conf ,

将其中的“fs.file-max = 51200”

修改为“fs.file-max = 512000”

  1. 然后使用 sysctl -p 命令,通知系统改参数已经修改,确认系统级的open files参数也已经修改了。
  2. 再次打开程序验证,就没有再出现 too many open files”的错误,程序可以正常运行了。

**********************************

附:网上一则对“too many open files”问题进行说明的文章:

运行在Linux系统上的Java程序可能会出现”Too many open files”的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景。

  1. 程序经常访问的文件、socketLinux中都是文件file,系统需要记录每个当前访问filenamelocationaccess authority等相关信息,这样的一个实体被称为file entry。“open files table”(图中橙色标识)存储这些file entry,以数组的形式线性管理。文件描述符(file descriptor)作为进程到open files table的指针,也就是open files table的下标索引,将每个进程与它所访问的文件关联起来了。

![Image 1][]

  1. 每个进程中都有一个file descriptor table管理当前进程所访问(open or create)的所有文件,文件描述符关联着open files table中文件的file entry。细节不表,对于open files table能容纳多少file entryLinux系统配置open files table的文件限制,如果超过配置值,就会拒绝其它文件操作的请求,并抛出Too many open files异常。这种限制有系统级和用户级之分。
  2. **系统级:**
  3. 系统级设置对所有用户有效。可通过两种方式查看系统最大文件限制
  4. 1 cat /proc/sys/fs/file-max
  5. 2 sysctl -a 查看结果中fs.file-max这项的配置数量
  6. 如果需要增加配置数量就修改/etc/sysctl.conf文件,配置fs.file-max属性,如果属性不存在就添加。
  7. 配置完成后使用sysctl -p来通知系统启用这项配置
  8. **用户级:**
  9. Linux限制每个登录用户的可连接文件数。可通过 ulimit -n来查看当前有效设置。如果想修改这个值就使用 ulimit -n <setting number> 命令。
  10. 对于文件描述符增加的比例,资料推荐是以2的幂次为参考。如当前文件描述符数量是1024,可增加到2048,如果不够,可设置到4096,依此类推。
  11. 在出现Too many open files问题后,首先得找出主要原因。最大的可能是打开的文件或是socket没有正常关闭。为了定位问题是否由Java进程引起,通过Java进程号查看当前进程占用文件描述符情况:

Java代码 ![复制代码][Image 1] ![收藏代码][Image 1]

  1. lsof -p $java_pid 每个文件描述符的具体属性
  2. lsof -p $java_pid | wc -l 当前Java进程file descriptor table中FD的总量
  1. 分析命令的结果,可判断问题是否由非正常释放资源所引起。

[Image 1]:

发表评论

表情:
评论列表 (有 0 条评论,337人围观)

还没有评论,来说两句吧...

相关阅读