Nginx PHP-FPM перестает работать, открытый сокет остается в соединении

#php #nginx

#php #nginx

Вопрос:

У меня эта повторяющаяся проблема с Nginx примерно раз в день, примерно дважды при высоких нагрузках на трафик. Исправить это просто, перезапустите сервер, но когда возникает ошибка, Nginx полностью перестает работать. У меня есть настройка NGINX PHP-FPM.

Проблема начинается с:

 020/09/27 09:57:27 [error] 38#38: *430982 upstream timed out (110: Connection timed out) while connecting to upstream, client: x.x.x.x, server: example.com, request: "POST /api/sessions/wri
  

И затем он переходит в:

 2020/09/27 10:03:22 [alert] 40#40: *431277 open socket #18 left in connection 51
2020/09/27 10:03:22 [alert] 38#38: *431298 open socket #34 left in connection 166
2020/09/27 10:03:22 [alert] 40#40: *431288 open socket #28 left in connection 59
2020/09/27 10:03:22 [alert] 38#38: *431296 open socket #32 left in connection 169
2020/09/27 10:03:22 [alert] 38#38: *431257 open socket #36 left in connection 177
2020/09/27 10:03:22 [alert] 38#38: *431291 open socket #23 left in connection 178
2020/09/27 10:03:22 [alert] 38#38: *431253 open socket #27 left in connection 188
2020/09/27 10:03:22 [alert] 38#38: *431300 open socket #31 left in connection 197
2020/09/27 10:03:22 [alert] 38#38: *431312 open socket #12 left in connection 204
2020/09/27 10:03:22 [alert] 38#38: *431259 open socket #38 left in connection 206
2020/09/27 10:03:22 [alert] 37#37: aborting
2020/09/27 10:03:22 [alert] 38#38: aborting
2020/09/27 10:03:22 [alert] 40#40: aborting
2020/09/27 10:03:23 [warn] 21568#21568: 8096 worker_connections exceed open file resource limit: 1024
2020/09/27 10:08:24 [warn] 21574#21574: *636 upstream server temporarily disabled while connecting to upstream,
  

Теперь запросы GET все еще работают. Поэтому, если я захожу на веб-сайт, он загружается. Но все, что POST, PUT или DELETE, завершится неудачей, поэтому в конечном итоге пользователи не могут ничего делать, кроме просмотра.

Есть идеи о том, почему это происходит? И есть ли проверка работоспособности, которую можно использовать для обнаружения этих проблем?

Комментарии:

1. Вам следует попробовать увеличить время ожидания запроса в NGINX.

2. @Md.MirajKhan, это может помочь, но это исправление для символов, а не причина проблемы.

Ответ №1:

Вероятно, ваш процесс Nginx открывает слишком много файлов. Вы можете увеличить это ограничение, следуя этой статье: Как увеличить количество открытых файлов в Linux

Чтобы изменить эту настройку, вам нужны права root и выполните следующие действия:

  1. Откройте файл /etc/security/limits.conf: vi /etc/security/limits.conf

  2. Добавьте эти строки в конец файла:

 ## Example hard limit for max opened files
*    hard    nofile    10240
## Example soft limit for max opened files
*    soft    nofile    10240
  
  1. Сохраните все изменения и перезагрузите свой сервер / VPS, чтобы применить новые настройки.

Примечание: число 10240 — это максимальное количество файлов, которые может открыть процесс. Измените это значение в соответствии с вашими потребностями.

Комментарии:

1. Мне не кажется, что основной причиной является количество открытых файлов, потому что первое сообщение касается времени ожидания. Поэтому я думаю, что в nginx остается много файлов, потому что восходящий поток (PHP-FPM в нашем случае) забит и не может обрабатывать запросы в разумные сроки. Я бы попытался поиграть с настройками PHP-FPM workers: возможно, добавить больше процессов или изменить весь режим запуска процесса. Смотрите эту статью о настройках PHP-FPM: tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning

Ответ №2:

О первой ошибке тайм-аута, которую вы видите, если вы используете конфигурацию fastcgi, вам может потребоваться просмотреть это:

 fastcgi_read_timeout 600s;
  

Убедитесь, что это значение больше, чем самая длинная обработка, которую будет выполнять PHP.

Вы также должны обязательно увеличить настройку рабочих подключений до любого ожидаемого количества одновременных подключений, которое вы ожидаете (скажем, 10000):

 worker_connections 10000;
  

Кроме того, как упоминалось в ответе @Sang Lu, вам необходимо убедиться, что NGINX может открывать достаточное количество дескрипторов файлов (включая также сетевые сокеты).
Если вы запустите главный процесс NGINX от имени root, вы можете просто выполнить (по крайней мере, 2 раза из worker_connections приведенной выше конфигурации:

 worker_rlimit_nofile 21000;
  

Другой способ — использовать ulimit или /etc/security/limits.conf для пользователя, который запускает главный процесс NGINX.