修改Linux FileDescription上限时的误区
1个进程能同时使用的File Description上限数的修改方法及修改时的注意事项。
在Linux系统能同时使用的File Description数是有上限的,系统整体的上限可在/proc/sys/fs/file-max文件里确认,有大量访问的服务器上会修改/etc/sysctl.conf文件来提高上限。
系统能使用的File Description上限之外,还有1个能使用的File Description的上限,而1个进程能使用的默认上限是1024。
当超过这个上限时,服务器的系统日志里会出现以下错误。
一般我们会使用以下方法修改1个进程可使用的File Description上限数
- 使用ulimit -n命令暂时修改上限
- 修改/etc/security/limits.conf文件
环境
- 环境:Amazon EC2 t2.micro
- 系统:CentOS 6.5 64位
- Web:HTTPD2.4
- PHP:5.3.3
ulimit是什么
ulimit是Shell的built-in命令,控制给进程分配的各种资源。(csh是使用limit命令)
用ulimit -n命令可以查看现在的File Description数上限(SoftLimit及HardLimit)。SoftLimit的值应小于HardLimit的值,并且 SoftLimit的值是一般用户也可修改。而HardLimit是只有root用户可以修改。
limits.conf是什么
/etc/security/limits.conf是,PAM认证模块之一的pam_limits的配置文件。配置文件的格式如下;
<domain> <type> <item> <value>
根据以上格式配置的话
root soft nofile 4096 root hard nofile 4096
即root用户执行的进程的最大File Description数是4096。
pam_limits模块,以session类型定义于PAM的配置文件/etc/pam.d/system-auth里,/etc/pam.d /login、/etc/pam.d/sshd、/etc/pam.d/sudo等多个配置文件以Include形式读取system-auth文件。
因此ulimit -n命令会在用户登录或者发生PAM认证(且在session里pam_limits模块被qeruire)时才会生效。
这就意味着「不进行PAM认证的Daemon类进程的上线,不能在/etc/security/limits.conf文件里修改」。
修改limits.conf后的误区(1)
修改limits.conf文件
# vi /etc/security/limits.conf * soft nofile 2048 * hard nofile 2048
之后,su(SwitchUser)到root之后,ulimit -n命令进行变更确认。
$ sudo su - Last login: Thu Jul 30 05:03:23 UTC 2015 on pts/0 # ulimit -n 2048
修改limits.conf后的误区(2)
修改limits.conf文件之后,重启Daemon之后会发现不再出现「Too many open files」错误了。
例如使用sudo service httpd restart时
- sudo到root用户时的PAM认证,会使limits.conf文件生效
- root用户启动httpd时,File Description的上限会被子进程(httpd)继承
- 在脚本里进行httpd的停止/启动时,httpd进程会继承父进程的File Description上限值
- httpd进程启动时继承了父进程的上限值
在Apache上限1024系统上,做了个简单的测试
1. 准备一个会同时使用1024个File Description的PHP脚本(index.php)
<?php $fp = array(); for ($i = 0; $i < 1100; $i++) { $fp[] = fopen('index.php', 'r'); } echo '<pre>'; var_dump($fp); echo '</pre>'; ?>
2. 通过Apache访问刚才的index.php文件
array(1100) { [0]=> resource(3) of type (stream) [1]=> resource(4) of type (stream) ~ 省略 ~ resource(1015) of type (stream) [1013]=> resource(1016) of type (stream) [1014]=> bool(false) [1015]=> bool(false) ~ 省略 ~
没有达到1024上限的理由是,httpd进程本身会使用一些File Description。可使用lsof命令进行查看。
Apache的错误日志(/var/log/httpd/error_log)里出现’Too many open files’
[Thu Jul 30 05:08:00.078564 2015] [:error] [pid 1150] [client X.X.X.X:1703] PHP Warning: fopen(index.php): failed to open stream: Too many open files in /var/www/html/index.php on line 4
3. 如下修改limits.conf文件
# vi /etc/security/limits.conf * soft nofile 2048 * hard nofile 2048
4. sudo service httpd restart重启Apache
5. 再次通过Apache访问index.php文件,会发现不再出现’Too many open files’错误
以下是访问index.php的结果。
array(1100) { [0]=> resource(3) of type (stream) [1]=> resource(4) of type (stream) ~ 省略 ~ resource(1101) of type (stream) [1099]=> resource(1102) of type (stream) }
6. 重启系统
7. 通过Apache访问index.php文件,会发现使用的File Description达到1000左右时,会出现’Too many open files’错误。
小结
修改Daemon类进程的File Description上限时不能使用/etc/security/limits.conf文件。
或者可以把ulimit -n追加到以下文件
- daemontools:/service/<服务名>/run文件
- rc脚本:/etc/init.d/<服务名>文件
修改上限之后,比如查看Apache进程的FileDescription上限时使用如下命令
# cat /proc/`pgrep httpd | head -1`/limits | grep 'open files' Max open files 1024 4096 files
系统使用File Description的情况,用如下命令查看
# cat /proc/sys/fs/file-nr 576 0 99006
CentOS7开始是Systemd启动各种Daemon,用什么方法修改File Description的上限呢。测试之后再和大家分享。