即使增加了 ulimit 和 sysctl,Apache 仍会出现“打开文件过多”错误

即使增加了 ulimit 和 sysctl,Apache 仍会出现“打开文件过多”错误

我正在使用 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 可以消除错误。

很抱歉问的问题和回答太快,但我想我会继续这样做,而不是删除这个问题,以防别人遇到这个问题。

相关内容