配置文件打开数

  1. 内核参数限制-总限制

/etc/sysctl.conf
file-max 是设置系统所有进程一共可以打开的文件数量,默认系统使用文件打开数为系统内存的10% 。
nr_open 是单个进程可分配的最大文件数,这个值通常默认是 1024*1024 (1048576)。

  1. limit限制-每个用户的最大值限制

/etc/security/limits.d/90-nproc.conf
soft 软限制值就是程序的最大打开文件数限值
hard 硬限制值就是限制用户的软限制值所能调整的最大上限

*          soft     nofile    2048000
*          hard     nofile    2048000

所以可以得出内核参数限制文件打开数是 总量、进程级别,而limit的限制的是 用户进程级别
内核配置limit 需要注意各个限制维度

** 文件打开数可以设置200w左右,一般情况是没有到限制数据,就会把系统的内存和cpu资源吃完了**

问题

内容摘自 https://blog.51cto.com/techsnail/2137383

1、网络连接是否会占用打开文件数?

会,一个listening或established状态的网络连接会占用一个打开文件数。所以,在web应用的访问量稍大时,如果是单进程程序的话,即便不算应用本身打开的常规文件,由于网络连接数多,也会导致打开文件数轻轻松松就超过1024个。所以,对于CentOS/RedHat 6这种老系统来说,由于默认值比较小,所以是很有必要调整的。

根据main文档中的说法,一个打开文件可能是一个常规文件、一个目录、一个块设备文件、一个字符设备文件、一个正在执行的文件引用、一个库、一个流或一个网络文件(网络socket,NFS文件或UNIX socket)。所以,网络连接也算。我估计,这可能是因为在程序中,要访问这些对象时,都有点类似于访问文件那样,需要打开。

2、当你修改了/etc/security/limits.conf文件中的ulimit限值(包括打开文件数)后,是否需要重启正在运行的程序?

是。因为ulimit限值是跟你当前的shell绑定的,你在哪个shell里面启动了程序,如果程序本身没有修改ulimit限值的话,程序就会继承那个shell环境的ulimit限值。所以,通常修改limits.conf文件中的限值后,要退出当前shell并重新登录,让新的限值生效,再重启你的程序。

当然,正如我前面所说,要查看一个进程运行后实际生效的ulimit限值,使用cat /proc/pid/limits命令。如果程序自身有修改ulimit限值的话,你就会看到它的实际限值与你当前shell环境的限值是不一样的。

3、是否修改了/etc/security/limits.conf文件中的ulimit限值(包括打开文件数)后,就能保证它对所有的程序生效?

这是错误的。事实上来说,limits.conf文件中的限值对通过启动脚本来启动的程序并不生效。比如,nginx程序有一个启动脚本/etc/init.d/nginx并设置了开机启动。那么,即便你修改了limits.conf文件中的限值,当服务器重启后,nginx程序自动启动了,它的ulimit限值将还会是默认值,而不会是你设置的值。当然,如果你此时登录进系统,并通过nginx开机启动脚本重启了nginx程序,nginx进程的ulimit限值自然会变为你在limits.conf文件中设置的限值。

关于这个问题的原因,我也没有找到什么权威的资料说明,但我估计可能是这样的。以CentOS 6系统为例,因为系统启动时,系统中的所有进程都是由第一支程序/sbin/init带起的。而limits.conf文件中的限值对/sbin/init程序并不生效,所以/sbin/init进程的ulimit限值仍然是默认值。这就导致它所启动的所有子进程,即系统中的所有其它程序,都继承它的ulimit限值,即默认值。

对于这个问题,我想到的有两种解决办法。

第一种,是在程序的启动脚本里面最前面加上ulimit修改命令:

[root@gw ~]# vim /etc/init.d/mysql

#!/bin/sh

ulimit -n 65535

第二种,就是,很多程序其实都支持在程序配置文件中修改程序的最大打开文件数,这样就不用管shell环境的ulimit限值是什么了。比如,nginx可以通过worker_rlimit_nofile指令来设置它的worker进程的最大打开文件数。诸如MySQL其实也是支持的。