Too many open files 是提供http服务的应用程序很容易遇到的问题, 通常是由于系统配置不当或者程序本身打开太多文件导致的, 于是网上有两种提示你解决该类问题的办法.

  1. 你的系统配置的最大文件打开数太低了
  2. 你的程序df泄露了

本篇内容主要围绕第一个原因展开描述,问题先从这个issue开始说起

这里有人回复:

Check your hard and soft limits for file descriptors (respectively ulimit -Hn and ulimit -Hs) and your (linux) kernel settings (cat /pro/sys/fs/file-max) as these may need to be adjusted.

这里提到3个概念

  1. ulimit -Hn
  2. ulimit -Hs
  3. /pro/sys/fs/file-max

带着这3个指标, 我们开始查阅资料

什么是ulimit

help ulimit # 注意这里的命令,请切换到bash上操作,而不是zsh

修改 shell 资源限制
在允许此类控制的系统上,提供对于 shell 及其创建的进程所可用的资源的控制。

由此,我们可以看出, 我们跑在linux上的大部分程序, 都是有shell所创建进程, 那么ulimit就如同一个配置文件, 限制了我们使用系统资源.

如果你使用help ulimit, 可以查看到如下参数配置项

选项:
  -S    使用 `soft'(软)资源限制
  -H    使用 `hard'(硬)资源限制
  -a    所有当前限制都被报告
  -b    套接字缓存尺寸
  -c    创建的核文件的最大尺寸
  -d    一个进程的数据区的最大尺寸
  -e    最高的调度优先级(`nice')
  -f    有 shell 及其子进程可以写的最大文件尺寸
  -i    最多的可以挂起的信号数
  -l    一个进程可以锁定的最大内存尺寸
  -m    最大的内存进驻尺寸
  -n    最多的打开的文件描述符个数
  -p    管道缓冲区尺寸
  -q    POSIX 信息队列的最大字节数
  -r    实时调度的最大优先级
  -s    最大栈尺寸
  -t    最大的CPU时间,以秒为单位
  -u    最大用户进程数
  -v    虚拟内存尺寸
  -x    最大的锁数量
  

这其中, 有我们关心的内容, 软资源和硬资源

什么是soft和hard

这里通过查阅资料整理如下:

  1. 理解soft和hard, 首先要想到是权限需求
  2. soft 必须小于hard
  3. hard严格的设定,必定不能超过这个设定的数值
  4. soft警告的设定,可以超过这个设定值,但是若超过则有警告信息
  5. 一个process可以修改当前process的soft或hard

ulimit的修改与生效

  1. ulimit的值总是继承父进程的设置。
  2. 可以利用ulimit设置当前shell进程
  3. 增加hard, 只能由root来

下面通过几个例子来践行上面的理论知识:

  1. 修改/etc/security/limits.conf
一条记录包含4️列,分别是范围domain(即生效的范围,可以是用户名、group名或*代表所有非root用户);t类型type:即soft、hard,或者-代表同时设置soft和hard;项目item,即ulimit中的资源控制项目,名字枚举可以参考文件中的注释;最后就是value。
* hard nofile 1000000 
* soft nofile 1000

Question: 修改后不重启当前shell, limits的修改是否生效
A: 否

  1. 当前shell配置ulimit
#!/bin/bash
ulimit -Sn 2045
nc -l 8888

然后ps -ef 查看nc的进程, 然后 cat /proc/{$pid}/limits

Max open files 2045 1000000 files

可以看到这里已经通过shell修改了soft nofile

修改系统最大的df数

除了ulimit控制外,/proc/sys/fs/file-max这个文件控制了系统内核可以打开的全部文件总数。所以,即便是ulimit里nofile设置为ulimited,也还是受限的。

系统级别: /proc/sys/fs/file-max

用户级别: /etc/security/limits.conf

单个进程: fs.nr_open

ulimit 常见命令

  • ulimit -a # 查看所有soft值
  • ulimit -Ha # 查看所有hard值
  • ulimit -Hn # 查看nofile的hard值
  • ulimit -Sn 1000 # 将nofile的soft值设置为1000
  • ulimit -n 1000 # 同时将nofiles的hard和soft值设置为1000

参考资料:
https://juejin.im/post/5d4cf32f6fb9a06b1d21312c
https://blog.csdn.net/liuleinevermore/article/details/83473919

标签: ulimit, soft, hard

评论已关闭