linux-可同时打开的文件数导致apache启动失败-文件句柄

碰到一个情况,有一台服务器,apache重启总是失败。查看apache的error_log发现只有一句话:

# /etc/init.d/httpd restart

Unable to open logs

检查了一下日志目录的权限,发现没有问题;检查了一下日志目录所在分区的空间使用情况,也不是没有空间引起的。那为什么打不开?用strace来启动并追踪一下系统调用,看看到底发生了什么?不过为了略去其它不必要的信息,我用grep命令对输出做了过滤

strace -f httpd -k start 2>&1|grep -v " ENOENT " | grep -Ee " E[A-Z]+"

linux-可同时打开的文件数导致apache启动失败

apache无法重启

终于发现了真正的问题所在:Too many open files。就是当前用户已经消耗掉系统允许的最大可同时打开的文件的数量限制。linux会限制每个用户最多可同时使用的文件句柄(文件描述符)数量。也就是每个用户最多可以同时打开多少个文件。

查看并修改Linux系统全局的最大可同时打开的文件数

可以通过下面的命令查看当前系统全局的文件打开数量限制

cat /proc/sys/fs/file-max

你可以这样直接修改系统全局的限制

echo “65535″ > /proc/sys/fs/file-max

但是这样修改系统重启后会失效。可直接编辑/etc/sysctl.conf文件,配置fs.file-max选项

vim /etc/sysctl.conf#添加

fs.file-max = 65535

然后可以通过sysctl命令让更改立马生效而不需要重启系统

sysctl -p /etc/sysctl.conf

好吧,改了之后,发现还是启动不了。怎么搞的?因为我们改的是系统全局的限制,也就是所有用户共享的,所有用户加到一起全部的可以同时打开的文件的个数。而apache启动失败,目前看来是启动apache的用户(root)受到了限制。

查看或设置某个用户的最大的同时打开的文件数

通常系统默认限制每个用户可以同时打开的文件数是1024。你可以通过

unlimit -n

命令来查看当前用户的数值。也可以直接在后面指定一个数值,临时设置当前用户的同时可打开文件数最大值,立即生效。

unlimit -n 50000

这个时候再尝试启动apache,发现已经可以启动了。但是这样修改是临时的,如果退出后重新登陆,再尝试重启你会发现失败的。你可以将这个命令添加到apache的启动脚本的头部。如果你不是root用户,你有可能碰到上面的命令执行失败。这是正常的。这个命令除root用户以外的用户执行的时候,只能将数值调整到系统给用户限制的硬限制值(hard limit)及以下,不能超过,超过就有会失败。只有root用户可以随意更改。

如果要查看其它的用户可以通过下面这个命令,比如我们要查看apache用户

su - apache -c 'ulimit -aHS' -s '/bin/bash'

上面的命令是通过su切换到apache用户,并使用bash这个shell来执行-c参数指定的命令。至于ulimit这个命令有兴趣可以去了解下。当然你如果不是root用户,你需要知道对应用户的密码了。相应的,也可以通过ulimit的-n参数来临时给指定用户设置一个限值。需要注意的是ulimit通过-n参数设置的值不能超过系统默认值或系统在/etc/security/limits.conf的限制。如果想想更改成更大的值或让设置的值重启后仍然有效,你只有通过修改/etc/security/limits.conf文件,看下面的示例:

#/etc/security/limits.conf

* hard nofile 500000

* soft nofile 500000

root hard nofile 500000

root soft nofile 500000

第一列作用域,可以是用户名,用户组,第二列是指限制类型,硬限制还是软限制,第三个指定限制的参数,我们这边是用nofile,就是指打开的文件数(我是理解成no. of open files,实际上是不是不知道了,只是助记),第四个就是参数值了。更详细的关于这个配置文件的信息,可以查看该文件的注释部分,有详细的说明。需要注意的是,修改完该文件,用户需要退出重新登陆才能生效。如果不想重新登陆,或者守护进程,需要再做一步操作才能让上面的限制生效:在/etc/pam.d/common-session文件添加下面这一行

session required pam_limits.so

推荐阅读