![即使增加了 ulimit 和 sysctl,Apache 仍会出现“打开文件过多”错误](https://linux22.com/image/741243/%E5%8D%B3%E4%BD%BF%E5%A2%9E%E5%8A%A0%E4%BA%86%20ulimit%20%E5%92%8C%20sysctl%EF%BC%8CApache%20%E4%BB%8D%E4%BC%9A%E5%87%BA%E7%8E%B0%E2%80%9C%E6%89%93%E5%BC%80%E6%96%87%E4%BB%B6%E8%BF%87%E5%A4%9A%E2%80%9D%E9%94%99%E8%AF%AF.png)
我正在使用 Locust 对运行 Apache(事件 MPM)和 PHP-FPM 的 Amazon Linux EC2 实例进行负载测试。当我使用 200 个用户(每秒约 28 个请求)运行负载测试时,一切正常。当我将用户数量增加到 300 个(每秒约 43 个请求)时,我开始在 Locust 日志中看到这些错误:
ConnectionError(MaxRetryError("HTTPConnectionPool(host='xxx.xxx.xxx.xxx', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x....>: Failed to establish a new connection: [Errno 24] Too many open files'))"))
在网上搜索后,我决定增加可用的打开文件描述符数量,看看是否可以解决这个问题。我编辑/etc/security/limits.conf
并设置了以下值(可能有些夸张,但我只是想看看是否有效果):
* soft nofile 65000
* hard nofile 65000
* soft nproc 10240
* hard nproc 10240
之后,我重新启动了 Apache 和 PHP-FPM:
sudo service httpd restart
sudo service php-fpm restart
我还查看了进程以验证新的限制并确保它们有效。Apache 的一个子进程:
$ cat /proc/22725/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 14745 14745 processes
Max open files 170666 170666 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 14745 14745 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
PHP-FPM 的一个子进程:
$ cat /proc/22963/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 10240 10240 processes
Max open files 10240 10240 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 14745 14745 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
我还在内核级别提高了最大打开文件数/etc/sysctl.conf
:
fs.file-max = 512000
然后我使用 保留了这些值sysctl -p
。同样,这可能太过分了,但我使用 的值也看到了相同的结果65000
。
在负载下,我只看到~4,200 个打开的文件,考虑到我提供的总体限制,这令人费解:
$ lsof | wc -l
4178
在这期间,我的 CPU 使用率从未超过 20%,并且我的服务器仍然有大约 3GB 的可用内存。
有任何想法吗?
答案1
在考虑了这个问题之后,我意识到问题可能根本不是在服务器端,而是在客户端(即我运行 Locust 的笔记本电脑)。事实上,ulimit -a
在这里检查得到了以下结果(运行 macOS 10.14.6):
➜ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 1418
-n: file descriptors 256
将文件描述符增加到 2048(ulimit -n 2048
)并在同一个 shell 中重新运行 Locust 可以消除错误。
很抱歉问的问题和回答太快,但我想我会继续这样做,而不是删除这个问题,以防别人遇到这个问题。