在linux系统上,默认情况下单个进程能打开的最大文件描述符的数量是1024,对于软件负载均衡进程来说,这个限制太低了。 通常情况下,软件负载均衡需要承载很高的并发连接,十万甚至百万都有可能。为了让负载均衡软件能建立那么多的并发连接, 需要提高进程能打开的文件描述符的数量。

查看当前的限制

在shell中,通过执行ulimit就可以看到当前的限制。例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 查看所有限制
$ 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) 127472
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) 127472
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

# 查看文件描述符的限制
$ ulimit -n
1024

提高限制

只对当前bash及其子进程

如果只需要临时的调整,通过ulimit就能快速实现。如下:

1
2
3
4
5
$ ulimit -n 4096
$ ulimit -n
4096
$ echo $(ulimit -n) # 查看子进程的限制
4096

如上所示,通过-n选项快速调整。调整后,自身的限制及子进程都是4096了。

不过这些调整都是临时的,如果你退出,重新登陆,这个值又改为默认值了

1
2
3
4
5
6
$ logout
Shared connection to 192.168.1.3 closed.
$ ssh 192.168.1.3
Last login: Thu Dec  5 16:27:27 2019 from 192.168.1.1
$ ulimit -n
1024

对所有登录用户及其子进程

在CentOS5/6系统上,如果要对所有登录用户生效,需要修改/etc/security/limits.conf, 在文件的默认添加如下的内容:

1
2
3
4
5
#<domain> <type>  <item>         <value>
*         soft    nproc          1000000
*         hard    nproc          1000000
*         soft    nofile         1000000
*         hard    nofile         1000000

上面将进程的文件描述符数量提高到100万。

不过到了CentOS 7,由于systemd替代了经典的sysv,而最开始systemd不支持全局的限制。 会忽略/etc/security/limits.conf中的配置。后来,在pam包中解决了。pam要生效, 需要确保在/etc/pam.d/login里面启用了pam_limit.so, 也就是说login的过程中会 加载session required pam_limit.so

保存后,需要重启系统,配置才能生效。

除了老办法,还可以通过修改systemd的配置文件来达到目的,systemd的配置文件路径如下:

  • 系统服务: /etc/systemd/system.conf/etc/systemd/system.conf.d/*.conf
  • 用户服务: /etc/systemd/user.conf/etc/systemd/user.conf.d/*.conf:

修改[Manager]下面的配置:

1
2
DefaultLimitNPROC=100000
DefaultLimitNOFILE=100000

修改完成后,需要重启服务(service)才能生效;

1
2
$ systemctl daemon-reload
$ systemctl restart xxx.service

对具体的服务及其子进程

如果只想修改某个服务,可以不改/etc/systemd/system.conf这些配置文件,可以修改service的配置文件, 在[Service]里面增加配置,如下:

1
2
3
4
[Service]
...
LimitNPROC=1000000
LimitNOFILE=1000000

修改完成后,同样要重启服务:

1
2
$ systemctl daemon-reload
$ systemctl restart xxx.service