Причины ошибки 500 сервера с nginx и php-fpm

Если вы когда-либо получали страницу «500 Internal Server Error», обслуживаемую вашим веб-сервером NGINX, вы можете быть озадачены тем, что на самом деле не так на самой странице:

Внутренняя ошибка сервера 500 NGINX

Понять, почему вы получаете ошибку NGINX, может быть непросто.

В этом посте я расскажу о двух основных причинах этой ошибки:

  • Проблемы, связанные с восходящим потоком, например, вызванные неисправными скриптами PHP.
  • Действительно внутренние проблемы NGINX.

Мы рассмотрим каждую категорию с примерами и решениями, чтобы дать вам полное понимание.

1. Проблемы, связанные с восходящим потоком, вызывающие 500 ошибок.

С точки зрения NGINX, восходящим потоком является любая серверная служба, для которой настроен NGINX, для получения содержимого страницы.
В качестве примера я буду использовать PHP-FPM, поскольку он все еще довольно популярен.

PHP-FPM — важная часть многих настроек NGINX, особенно при работе с веб-сайтами PHP, такими как WordPress.
NGINX действует как обратный прокси-сервер, направляя запросы на обработку в PHP-FPM.

Распространенным сценарием, в результате которого NGINX обслуживает страницу внутренней ошибки сервера, является неисправный PHP-скрипт с синтаксическими ошибками или исключениями PHP во время выполнения. Такие проблемы могут вызвать ошибку 500, как на изображении выше, особенно если настройка fastcgi_intercept_errors выполняется on в NGINX. Эта конфигурация заставляет NGINX обрабатывать ошибки восходящего потока как свои собственные, поэтому вместо ошибок, сгенерированных PHP, вы видите ошибку, сгенерированную самим NGINX.

Решение внутренней ошибки сервера 500 в NGINX, вызванной PHP:

Простое исправление PHP-скриптов избавит вас от ошибки в NGINX.

В качестве слишком упрощенного примера этот фрагмент PHP-скрипта содержит синтаксическую ошибку, в которой отсутствует конечная точка с запятой:

<?php
echo "Hello, World"

Когда NGINX настроен с:

location ~ \.php$ {
 error_page 500 /500.html;
 fastcgi_intercept_errors on;

 fastcgi_pass unix:/path/to/php-fpm.sock;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 include fastcgi_params;
...
}

Скрипт заставит NGINX выдать ошибку 500.

Правильный скрипт решит проблему:

<?php
echo "Hello, World";

На реальном веб-сайте со сложными PHP-скриптами вам потребуется:

  • Включить ведение журнала ошибок PHP: настройте PHP для регистрации ошибок для получения подробной информации.
  • Отладка и исправление PHP-скрипта. Используйте такие инструменты, как Xdebug, для выявления и устранения проблем в скрипте.

Реализация эффективной обработки ошибок

Некоторые ошибки в PHP можно допустить и устранить с помощью механизма обработки исключений. Это применимо для случаев взаимодействия с внешними API-сервисами, когда вы не можете гарантировать постоянную доступность и отказоустойчивость внешних сервисов. Правильная обработка ошибок в таких PHP-скриптах может предотвратить многие 500 ошибок.

Перехватывайте исключения и корректно обрабатывайте ошибки, чтобы не передавать их в NGINX. Пример фрагмента кода для обработки ошибок:

try {
 // Code that may throw an exception, e.g. talking to external API
} catch (Exception $e) {
 error_log($e->getMessage());
 // Handle the exception
}

2. Действительно внутренние проблемы NGINX

Внутренние проблемы сервера в NGINX

Помимо PHP-FPM и других проблем восходящего потока, сам NGINX может столкнуться с проблемами, приводящими к ошибке 500. Они часто связаны с ошибками выделения ресурсов или внутренними логическими ошибками. Хотя мы говорим о таких ошибках как о «внутренних ошибках сервера», на самом деле они больше связаны с проблемами серверной среды, в которой работает NGINX. На самом деле это редко, если вообще когда-либо, является ошибкой NGINX.

Пример: ошибка выделения памяти.

NGINX динамически распределяет память при обработке ввода запроса и доставке ответа. Такое распределение в исходном коде NGINX часто выполняется следующим образом:

b = ngx_calloc_buf(r->pool);
if (b == NULL) {
 return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

В этом коде NGINX пытается выделить буфер для ответа, используя ngx_calloc_buf(r->pool). Затем он выполняет проверку на сбой: если выделение не удалось (b == NULL), то NGINX возвращает внутреннюю 500ошибку сервера. Это указывает на реальную проблему сервера, из-за которой NGINX не может выделить необходимую память.

Решение состоит в том, чтобы:

  • убедитесь, что достаточно доступной оперативной памяти, например, запустив free -h
  • оптимизировать конфигурацию сервера для приложений, требующих большого объема памяти, например, путем настройки количества рабочих PHP-FPM или количества разрешенных соединений/буферов в MySQL.
  • обеспечить конфигурацию подкачки для обработки всплесков трафика
  • обновите оперативную память сервера, если необходимо

Чтобы заблаговременно предотвратить ошибку в будущем, отслеживайте ресурсы сервера с помощью таких инструментов, как NGINX Amplify.

Обработка событий чтения и записи.

Обработка NGINX событий чтения и записи также может привести к 500 ошибкам, если во время этих операций возникнут проблемы.

Пример. Ошибка обработки события чтения.

Рассмотрим этот отрывок из исходного кода NGINX:

if (ngx_handle_read_event(r->connection->read, 0)!= NGX_OK) {
 return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

В этом фрагменте NGINX пытается обработать событие чтения. Если обработка события чтения не удалась, NGINX возвращает 500ошибку. Это предполагает внутреннюю проблему сервера при управлении клиентскими соединениями или обработке данных.

Чтобы найти правильное решение, покопайтесь в выводе dmesg, проверьте журналы ошибок NGINX, а также понаблюдайте за текущей загрузкой ЦП.

Например, количество рабочих процессов NGINX может влиять на использование ресурсов. Если у вас настроено слишком много рабочих процессов, это может привести к перегрузке системных ресурсов. Настройте директиву worker_processes в конфигурации NGINX в зависимости от мощности вашего сервера. Значение auto — разумное значение по умолчанию.

Другая возможная причина заключается в том, что если достигнут системный лимит на файловые дескрипторы, это может привести к той же ужасной ошибке 500. Эту проблему можно решить, указав больший параметр worker_rlimit_nofile в конфигурации NGINX:

  • используйте команду ulimit -n, чтобы проверить текущий предел дескриптора файла для пользователя NGINX.
  • убедитесь, что значение worker_rlimit_nofile установлено выше или равно этому пределу, например worker_rlimit_nofile 4096;

Внутренняя ошибка 500, выдаваемая NGINX, также может быть вызвана рабочей нагрузкой, и в зависимости от анализа журналов вам может потребоваться настроить балансировку нагрузки или выполнить обновление сервера для решения проблемы. Прежде чем это сделать, убедитесь, что настройки вашего кэша оптимальны и что вы используете хорошее решение для полностраничного кэширования, например Varnish Cache.

Вывод: решение внутренней ошибки сервера 500 в NGINX

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

Часто задаваемые вопросы: краткая информация по типичным вопросам.

  1. Когда мне следует заподозрить проблему PHP-FPM в сценарии ошибки 500?
    Если ошибка возникает во время выполнения PHP-скрипта, особенно когда fastcgi_intercept_errors включен, скорее всего, это проблема, связанная с PHP-FPM.
  2. Каковы общие индикаторы внутренних проблем NGINX, приводящих к 500 ошибкам?
    Ищите ошибки, связанные со сбоями выделения памяти или проблемами при обработке клиентских подключений, в журналах NGINX.
  3. Как я могу предотвратить ошибки 500, связанные с PHP-FPM?
    Внедрите надежную обработку ошибок в свои сценарии PHP и убедитесь, что PHP-FPM настроен правильно.
  4. Какие шаги я могу предпринять, чтобы минимизировать внутренние ошибки NGINX 500?
    Регулярно отслеживайте ресурсы сервера, оптимизируйте конфигурации NGINX и следите за тем, чтобы сервер не был перегружен.
  5. Важно ли обновлять NGINX и PHP-FPM?
    Абсолютно. Регулярные обновления могут исправить известные ошибки и повысить производительность, снижая вероятность возникновения 500 ошибок.

Понимание и устранение внутренней ошибки сервера 500 в NGINX требует сочетания знаний PHP-скриптов и навыков управления сервером NGINX. Благодаря этому руководству вы сможете эффективно диагностировать и устранять эти ошибки.