介绍
在Linux下有时会遇到Socket/File : Can't open so many files的问题。其实Linux是有文件句柄限制的,而且Linux默认一般都是1024(阿里云主机默认是65535)。在生产环境中很容易到达这个值,因此这里就会成为系统的瓶颈。
1.查看方法
使用ulimit -a 或者 ulimit -n
open files (-n) 1024 是linux操作系统对一个进程打开的文件句柄数量的限制(也包含打开的套接字数量)
这里只是对用户级别的限制,其实还有个是对系统的总限制,查看系统总线制:
# cat /proc/sys/fs/file-max
man proc,可得到file-max的描述:
/proc/sys/fs/file-max
This file defines a system-wide limit on the number of open files for all processes. (See
also setrlimit(2), which can be used by a process to set the per-process limit,
RLIMIT_NOFILE, on the number of files it may open.) If you get lots of error messages
about running out of file handles, try increasing this value:
即file-max是设置系统所有进程一共可以打开的文件数量 。同时一些程序可以通过setrlimit调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值。
也就是说,这项参数是系统级别的。
2.修改方法
临时生效:
# ulimit -SHn 10000
其实ulimit 命令身是分软限制和硬限制,加-H就是硬限制,加-S就是软限制。默认显示的是软限制,如果运行ulimit 命令修改时没有加上-H或-S,就是两个参数一起改变。
软限制和硬限制的区别?
硬限制就是实际的限制,而软限制是警告限制,它只会给出警告。
永久生效
要想ulimits 的数值永久生效,必须修改配置文件/etc/security/limits.conf
在该配置文件中添加
* hard nofile 65535
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
* 表示所用的用户
修改系统总限制
其实上的修改都是对一个进程打开的文件句柄数量的限制,我们还需要设置系统的总限制才可以。
假如,我们设置进程打开的文件句柄数是1024 ,但是系统总线制才500,所以所有进程最多能打开文件句柄数量500。从这里我们可以看出只设置进程的打开文件句柄的数量是不行的。所以需要修改系统的总限制才可以。
echo 6553560 > /proc/sys/fs/file-max
上面是临时生效方法,重启机器后会失效;
永久生效方法:
修改 /etc/sysctl.conf, 加入
fs.file-max = 6553560 重启生效
Nginx 进程最大可打开文件数
worker_processes:操作系统启动多少个工作进程运行Nginx。注意是工作进程,不是有多少个nginx工程。在Nginx运行的时候,会启动两种进程,一种是主进程master process;一种是工作进程worker process。例如我在配置文件中将worker_processes设置为4,启动Nginx后,使用进程查看命令观察名字叫做nginx的进程信息,我会看到如下结果:
-
[root@localhost nginx]# ps -elf | grep nginx
-
4 S root 2203 2031 0 80 0 - 46881 wait 22:18 pts/0 00:00:00 su nginx
-
4 S nginx 2204 2203 0 80 0 - 28877 wait 22:18 pts/0 00:00:00 bash
-
5 S root 2252 1 0 80 0 - 11390 sigsus 22:20 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
-
5 S nobody 2291 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2292 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2293 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2294 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
0 R root 2312 2299 0 80 0 - 28166 - 22:24 pts/0 00:00:00 grep --color=auto nginx
1个nginx主进程,master process;还有四个工作进程,worker process。主进程负责监控端口,协调工作进程的工作状态,分配工作任务,工作进程负责进行任务处理。一般这个参数要和操作系统的CPU内核数成倍数。
worker_connections:这个属性是指单个工作进程可以允许同时建立外部连接的数量。无论这个连接是外部主动建立的,还是内部建立的。这里需要注意的是,一个工作进程建立一个连接后,进程将打开一个文件副本。所以这个数量还受操作系统设定的,进程最大可打开的文件数有关。
设置Nginx进程最大可打开文件数
1、更改操作系统级别的“进程最大可打开文件数”的设置
2、更改Nginx软件级别的“进程最大可打开文件数”的设置
刚才更改的只是操作系统级别的“进程最大可打开文件”的限制,作为Nginx来说,我们还要对这个软件进行更改。打开nginx.conf主配置文件。您需要配合worker_rlimit_nofile属性。如下:
user root root;
worker_processes 4;
worker_rlimit_nofile 65535;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535;
}
请注意代码行中加粗的两个配置项,请一定两个属性全部配置。
验证Nginx的“进程最大可打开文件数”是否起作用
那么我们如何来验证配置是否起作用了呢?在linux系统中,所有的进程都会有一个临时的核心配置文件描述,存放路径在 /pro/进程号/limit。
首先我们来看一下,没有进行参数优化前的进程配置信息:
-
[root@localhost nginx]# ps -elf | grep nginx
-
4 S root 2203 2031 0 80 0 - 46881 wait 22:18 pts/0 00:00:00 su nginx
-
4 S nginx 2204 2203 0 80 0 - 28877 wait 22:18 pts/0 00:00:00 bash
-
5 S root 2252 1 0 80 0 - 11390 sigsus 22:20 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
-
5 S nobody 2291 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2292 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2293 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
5 S nobody 2294 2252 0 80 0 - 11498 ep_pol 22:23 ? 00:00:00 nginx: worker process
-
0 R root 2318 2299 0 80 0 - 28166 - 22:42 pts/0 00:00:00 grep --color=auto nginx
可以看到,nginx工作进程的进程号是:2291 2292 2293 2294。我们选择一个进程,查看其核心配置信息:
-
[root@localhost nginx]# cat /proc/2291/limits
-
Limit Soft Limit Hard Limit Units
-
Max cpu time unlimited unlimited seconds
-
Max file size unlimited unlimited bytes
-
Max data size unlimited unlimited bytes
-
Max stack size 8388608 unlimited bytes
-
Max core file size 0 unlimited bytes
-
Max resident set unlimited unlimited bytes
-
Max processes 3829 3829 processes
-
Max open files 1024 4096 files
-
Max locked memory 65536 65536 bytes
-
Max address space unlimited unlimited bytes
-
Max file locks unlimited unlimited locks
-
Max pending signals 3829 3829 signals
-
Max msgqueue size 819200 819200 bytes
-
Max nice priority 0 0
-
Max realtime priority 0 0
-
Max realtime timeout unlimited unlimited us
请注意其中的Max open files ,分别是1024和4096。那么更改配置信息,并重启Nginx后,配置信息就是下图所示了:
-
[root@localhost conf]# cat /proc/2351/limits
-
Limit Soft Limit Hard Limit Units
-
Max cpu time unlimited unlimited seconds
-
Max file size unlimited unlimited bytes
-
Max data size unlimited unlimited bytes
-
Max stack size 8388608 unlimited bytes
-
Max core file size 0 unlimited bytes
-
Max resident set unlimited unlimited bytes
-
Max processes 3829 3829 processes
-
Max open files 65535 65535 files
-
Max locked memory 65536 65536 bytes
-
Max address space unlimited unlimited bytes
-
Max file locks unlimited unlimited locks
-
Max pending signals 3829 3829 signals
-
Max msgqueue size 819200 819200 bytes
-
Max nice priority 0 0
-
Max realtime priority 0 0
-
Max realtime timeout unlimited unlimited us