Я выполняю нагрузочное тестирование экземпляра 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 в той же оболочке позволил устранить ошибки.
Извините за быстрый вопрос и ответ, но я подумал, что буду продолжать в том же духе, а не удалять вопрос, если кто-то еще столкнется с этой проблемой.