Linux命令-按照与使用(14)报错:too many open files(打开的文件过多)解决方法:limit资源限制ulimit

https://www.cnblogs.com/conanwang/p/5818441.html

SU: failed to execute /bin/bash:系统中打开的文件过多

一、产生原因

too many open files(打开的文件过多)是Linux系统中常见的错误,从字面意思上看就是说程序打开的文件数过多,不过这里的files不单是文件的意思,也包括打开的通讯链接(比如socket),正在监听的端口等等,所以有时候也可以叫做句柄(handle),这个错误通常也可以叫做句柄数超出系统限制。
引起的原因就是进程在某个时刻打开了超过系统限制的文件数量以及通讯链接数,通过命令ulimit -a可以查看当前系统设置的最大句柄数是多少:

ulimit -a
其中 open files (-n) 65535 表示每个用户最大允许打开的文件数量是65535 。 默认是1024。1024很容易不够用。

open files那一行就代表系统目前允许单个进程打开的最大句柄数,这里是1024。
使用命令lsof -p 进程id可以查看单个进程所有打开的文件详情,使用命令lsof -p 进程id | wc -l可以统计进程打开了多少文件:

[tomcat@localhost bin]$ jps
3092 Bootstrap
3197 Jps
[tomcat@localhost bin]$ lsof -p 3092 | wc -l
108

以裸启动的tomcat为例,可以看到它目前打开了108个文件数,如果文件数过多使用lsof -p 进程id命令无法完全查看的话,可以使用lsof -p 进程id > openfiles.log将执行结果内容输出到日志文件中查看。

二、解决方法

ulimit -a 用来显示当前的各种用户进程限制
ulimit -Sn 查看软限制
ulimit -n 查看软限制
ulimit -Hn 查看硬限制
ulimit -c 查看core文件大小
ulimit -m 查看内存的上限
ulimit -s 查看设定资源的弹性限制,堆栈大小

ulimit命令,功能说明
ulimit命令
功能说明:控制shell程序的资源。

语  法:ulimit [-aHS][-c <core文件上限>][-d <数据节区大小>][-f <文件大小>][-m <内存大小>][-n <文件数目>][-p <缓冲区大小>][-s <堆叠大小>][-t <CPU时间>][-u <程序数目>][-v <虚拟内存大小>]

补充说明:ulimit为shell内建指令,可用来控制shell执行程序的资源。

参  数:
   -a  显示目前资源限制的设定。 
   -c <core文件上限>  设定core文件的最大值,单位为区块。 
   -d <数据节区大小>  程序数据节区的最大值,单位为KB。 
   -f <文件大小>  shell所能建立的最大文件,单位为区块。 
   -H  设定资源的硬性限制,也就是管理员所设下的限制。 
   -m <内存大小>  指定可使用内存的上限,单位为KB。 
   -n <文件数目>  指定同一时间最多可开启的文件数。 
   -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。 
   -s <堆叠大小>  指定堆叠的上限,单位为KB。 
   -S  设定资源的弹性限制。 
   -t <CPU时间>  指定CPU使用时间的上限,单位为秒。 
   -u <程序数目>  用户最多可开启的程序数目。 
   -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB。

1、 增大允许打开的文件数——命令方式 临时修改

ulimit -HSn 65536 // 设置用户最大允许打开文件数量,这只是在当前终端有效,退出之后,open files又变为默认值。当然也可以写到/etc/profile中,因为每次登录终端时,都会自动执行/etc/profile
ulimit -c unlimited //设置core文件大小为不限制大小,就可以把core文件的大小设置为无限大,同时也可以使用数字来替代unlimited,对core文件的上限制做更精确的设定。

ulimit -HSn 102400 临时终端生效,切换终端失败
[root@localhost 20221108]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 126906
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024   <==文件数
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 126906
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[root@localhost 20221108]# 
[root@localhost 20221108]# ulimit -HSn 102400  
[root@localhost 20221108]# 
[root@localhost 20221108]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 126906
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 102400  <==文件数
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 126906
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

2、 增大允许打开的文件数——修改系统配置文件 永久修改(limits.conf)

2.1.修改file-max

/proc/sys/fs/file-max中指定了系统范围内所有进程可打开的文件句柄的数量限制

# echo  6553560 > /proc/sys/fs/file-max  //sysctl -w "fs.file-max=34166",前面2种重启机器后会恢复为默认值# vim /etc/sysctl.conf, 加入以下内容,重启生效
fs.file-max = 6553560

fs.file-max = 6815744
fs.file-max指系统能够打开最大的文件句柄数
建议设置:fs.file-max=512processes=6.51024*1024=6.5M
Oracle系统内核参数、资源限制及ipcs相关命令总结

2.2.修改ulimit的open file,系统默认的ulimit对文件打开数量的限制是1024 ,永久生效的方法:修改/etc/security/limits.conf文件

/etc/security/limits.conf 文件实际是 Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so 的配置文件,而且只针对于单个会话。 该设置不会影响系统服务的资源限制。还要注意 /etc/security/limits.d/ 的这个目录,

# vim /etc/security/limits.conf  //加入以下配置,重启即可生效
#在最后加入  
* soft nofile 65535  # * 表示所有用户
* hard nofile 65535  # * 表示所有用户****
ubu soft nofile 8192  # ubu 表示ubu用户
roy hard nofile 8192  # roy 表示roy用户
ubu soft nofile 8192  # ubu 表示ubu用户
roy hard nofile 8192  # roy 表示roy用户

* soft noproc 20000  #软连接   
* hard noproc 20000  #硬连接  

或者只加入
 * - nofile 8192  

最前的 * 表示所有用户,可根据需要设置某一用户,例如
soft nproc :单个用户可用的最大进程数量(超过会警告); 是代表最大进程数
hard nproc:单个用户可用的最大进程数量(超过会报错); 是代表最大进程数
soft nofile  :可打开的文件描述符的最大数(超过会警告);是代表最大文件打开数
hard nofile :可打开的文件描述符的最大数(超过会报错);是代表最大文件打开数
重启系统之后生效。

注意”nofile”项有两个可能的限制措施。就是项下的hard和soft。 要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用”-“字符设定, 则hard和soft设定会同时被设定。

①一般soft的值会比hard小,也可相等。

②/etc/security/limits.d/里面配置会覆盖/etc/security/limits.conf的配置

③只有root用户才有权限修改/etc/security/limits.conf

④如果limits.conf没有做设定,则默认值是1024

3、检查程序问题

如果你对你的程序有一定的解的话,应该对程序打开文件数(链接数)上限有一定的估算,如果感觉数字异常,请使用第一步的lsof -p 进程id > openfiles.log命令,获得当前占用句柄的全部详情进行分析,

1)打开的这些文件是不是都是必要的?
2)定位到打开这些文件的代码
3)是否程序操作了文件写入,但是没有进行正常关闭
4)是否程序进行了通讯,但是没有正常关闭(也就是没有超时结束的机制)

如果程序中存在这些问题的话,无论系统句柄数设置的多么大,随着时间的推移,也一定会占用完。

附录:

附录1.
为了让一个程序的open files数目扩大,可以在启动脚本前面加上ulimit -HSn 102400命令。但当程序是一个daemon时,可能这种方法无效,因为没有终端。

附录2.
如果某项服务已经启动,再动态调整ulimit是无效的,特别是涉及到线上业务就更麻烦了。
这时,可以考虑通过修改/proc/’程序pid’/limits来实现动态修改!!!

A /etc/security/limits.conf配置解析

/etc/security/limits.conf配置解析
# /etc/security/limits.conf
#
#This file sets the resource limits for the users logged in via PAM.
该文件为通过PAM登录的用户设置资源限制。
#It does not affect resource limits of the system services.
#它不影响系统服务的资源限制。
#Also note that configuration files in /etc/security/limits.d directory,
#which are read in alphabetical order, override the settings in this
#file in case the domain is the same or more specific.
请注意/etc/security/limits.d下按照字母顺序排列的配置文件会覆盖 /etc/security/limits.conf中的
domain相同的的配置
#That means for example that setting a limit for wildcard domain here
#can be overriden with a wildcard setting in a config file in the
#subdirectory, but a user specific setting here can be overriden only
#with a user specific setting in the subdirectory.
这意味着,例如使用通配符的domain会被子目录中相同的通配符配置所覆盖,但是某一用户的特定配置
只能被字母路中用户的配置所覆盖。其实就是某一用户A如果在/etc/security/limits.conf有配置,当
/etc/security/limits.d子目录下配置文件也有用户A的配置时,那么A中某些配置会被覆盖。最终取的值是 /etc/security/limits.d 下的配置文件的配置。

#
#Each line describes a limit for a user in the form:
#每一行描述一个用户配置
#<domain> <type> <item> <value>

#Where:
#<domain> can be:
# - a user name    一个用户名
# - a group name, with @group syntax    用户组格式为@GROUP_NAME
# - the wildcard *, for default entry    默认配置为*,代表所有用户
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit 
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits 
# - "hard" for enforcing hard limits
有soft,hard和-,soft指的是当前系统生效的设置值,软限制也可以理解为警告值。
hard表名系统中所能设定的最大值。soft的限制不能比hard限制高,用-表名同时设置了soft和hard的值。
#<item> can be one of the following:    <item>可以使以下选项中的一个
# - core - limits the core file size (KB)    限制内核文件的大小。
# - data - max data size (KB)    最大数据大小
# - fsize - maximum filesize (KB)    最大文件大小
# - memlock - max locked-in-memory address space (KB)    最大锁定内存地址空间
# - nofile - max number of open file descriptors 最大打开的文件数(以文件描叙符,file descripter计数) 
# - rss - max resident set size (KB) 最大持久设置大小
# - stack - max stack size (KB) 最大栈大小
# - cpu - max CPU time (MIN)    最多CPU占用时间,单位为MIN分钟
# - nproc - max number of processes 进程的最大数目
# - as - address space limit (KB) 地址空间限制 
# - maxlogins - max number of logins for this user    此用户允许登录的最大数目
# - maxsyslogins - max number of logins on the system    系统最大同时在线用户数
# - priority - the priority to run user process with    运行用户进程的优先级
# - locks - max number of file locks the user can hold    用户可以持有的文件锁的最大数量
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19] max nice优先级允许提升到值
# - rtprio - max realtime pr iority
#
#<domain> <type> <item> <value>
#

#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@st

A.1 /etc/security/limits.d/目录

/etc/security/limits.d/ 目录
该目录下默认有 *-nproc.conf 文件,该文件是用于限制用户的线程限制。我们也可以在该目录创建配置文件在 /etc/security/limits.d/ 下,以 .conf 结尾。
centos 7

在CentOS 7版本中为/etc/security/limits.d/20-nproc.conf

# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

*          soft    nproc     4096 # 所有的用户默认可以打开最大的进程数为 4096
root       soft    nproc     unlimited # root 用户默认可以打开最大的进程数 无限制的。

CentOS 6

在CentOS 6版本中为 /etc/security/limits.d/90-nproc.conf

B ulimit 如何配置

B.1注意事项

注意不能设置 nofile不能设置 unlimitednoproc可以.
当我们设置了 nofile不能设置 unlimited后,我们进行 ssh 登录,是登录不了的,并且报错下面的内容。

Dec  1 14:57:57 localhost sshd[1543]: pam_limits(sshd:session): Could not set limit for 'nofile': Operation not permitted

当我们设置的 nofile 的值可以设置的最大值为 1048576(2**20),设置的值大于该数,就会进行登录不了。也会显示上面的登录错误。(亲测)

B.2 基础配置

我们不将所有的配置配置在/etc/security/limits.conf 而是将配置放在 /etc/security/limits.d/ 下。
比如我们将 nofile的配置放在 /etc/security/limits.d/20-nofile.conf ,nproc 的配置放在 /etc/security/limits.d/20-nproc.conf.

一般我们需要配置的 /etc/security/limits.d/20-nofile.conf 为。

root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535

/etc/security/limits.d/20-nproc.conf 设置为

*    -     nproc   65535
root soft  nproc  unlimited
root hard  nproc  unlimited

B.3注意覆盖点的问题。

示例一:
/etc/security/limits.conf 配置了:

root soft nofile 65538
root hard nofile 65538
* soft nofile 65539
* hard nofile 65539

这个root 用户的 默认取值是 65538 ,* 统配符虽然在 root 配置后面,但是 root 的配置只能被 root 进行覆盖。

我们看下这个配置,当这样配置的时候

root soft nofile 65538
root hard nofile 65538
* soft nofile 65539
* hard nofile 65539
root soft nofile 65539

这个的 root 用户的取值还是 65538 ,因为虽然 root soft nofile 65539 会覆盖我们之前的配置,但是这个配置是不生效的。因为 root soft nofile 65539 配置的值大于root hard nofile 65538 , soft 配置的值不能大于 hard.
示例二:
当我们在 /etc/security/limits.conf 配置了:

root soft nofile 65538
root hard nofile 65538
* soft nofile 65539
* hard nofile 65539

然后我们在 /etc/security/limits.d/20-nofile.conf 配置了:

root soft nofile 65536
root hard nofile 65536
* soft nofile 65540
* hard nofile 65540

最后的取值是会取 /etc/security/limits.d/20-nofile.conf 里面的值
配置,只能被特定覆盖。
/etc/security/limits.d/ 下文件的相同配置可以覆盖 /etc/security/limits.conf
softhard需要都进行设置,才能生效。
nofile不能设置 unlimited
nofile可以设置的最大值为 1048576(2**20),设置的值大于该数,就会进行登录不了。
soft 设置的值 一定要小于或等于 hard 的值。

C、ulimit 配置后生效

临时配置

设置可以打开文件的最大数为 65536

ulimit  -SHn  65536

重启后失效。

永久配置

配置到配置文件/etc/security/limits.conf或者 /etc/security/limits.d/ 中。
然后退出当前会话,重新登录。 即可生效,重启配置也会保留。

配置不生效的问题

2020年3月份补充
SSH 登陆 limits 配置不生效解决办法

D、ulimit 常用命令

ulimit 常用命令
      -S	use the `soft' resource limit # 设置软限制
      -H	use the `hard' resource limit # 设置硬限制
      -a	all current limits are reported# 显示所有的配置。
      -b	the socket buffer size # 设置socket buffer 的最大值。
      -c	the maximum size of core files created # 设置core文件的最大值.
      -d	the maximum size of a process's data segment  # 设置线程数据段的最大值
      -e	the maximum scheduling priority (`nice') # 设置最大调度优先级
      -f	the maximum size of files written by the shell and its children # 创建文件的最大值。
      -i	the maximum number of pending signals # 设置最大的等待信号
      -l	the maximum size a process may lock into memory #设置在内存中锁定进程的最大值
      -m	the maximum resident set size 
      -n	the maximum number of open file descriptors # 设置最大可以的打开文件描述符。
      -p	the pipe buffer size
      -q	the maximum number of bytes in POSIX message queues
      -r	the maximum real-time scheduling priority
      -s	the maximum stack size
      -t	the maximum amount of cpu time in seconds
      -u	the maximum number of user processes  # 设置用户可以创建的最大进程数。
      -v	the size of virtual memory  # 设置虚拟内存的最大值
      -x	the maximum number of file locks


查看配置

查看所有的配置

ulimit -a
查看配置的最大打开文件数

ulimit -n

更改配置

ulimit -SHn 65536

posted @   muzlei  阅读(1061)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· [翻译] 为什么 Tracebit 用 C# 开发
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 刚刚!百度搜索“换脑”引爆AI圈,正式接入DeepSeek R1满血版
点击右上角即可分享
微信分享提示