Назад | Перейти на главную страницу

«Слишком много открытых файлов» Ошибка Apache даже с увеличенными ulimit и sysctl

Я выполняю нагрузочное тестирование экземпляра Amazon Linux EC2 с Apache (событие MPM) и PHP-FPM с использованием Locust. Когда я запускаю нагрузочный тест с 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.

Под нагрузкой я вижу только ~ 4200 открытых файлов, что вызывает недоумение, учитывая общие ограничения, которые я указал:

$ lsof | wc -l
4178

Во время всего этого загрузка моего процессора никогда не превышает 20%, а на моем сервере все еще остается около 3 ГБ свободной памяти.

Любые идеи?

После того, как я проспал эту проблему, я понял, что проблема может быть вовсе не на стороне сервера, а на стороне клиента (то есть на моем ноутбуке с 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) и повторный запуск Locust в той же оболочке позволил устранить ошибки.

Извините за быстрый вопрос и ответ, но я подумал, что буду продолжать в том же духе, а не удалять вопрос, если кто-то еще столкнется с этой проблемой.