🌐 Как исправить распространенные ошибки веб-сервера Nginx

Мануал

Nginx – очень популярный веб-сервер в наши дни.

В этой статье мы расскажем вам о некоторых распространенных ошибках при работе веб-сервера Nginx и возможных решениях.

Это не полный список.

Если вы все еще не можете устранить ошибку, попробовав предложенные решения, пожалуйста, проверьте логи сервера Nginx в каталоге /var/log/nginx/ и поищите в Google, чтобы отладить проблему.

Unable to connect/Refused to Connect

Если при попытке получить доступ к вашему сайту вы видите следующую ошибку:

Firefox can’t establish a connection to the server at www.example.com

или

www.example.com refused to connect

или

The site can't be reached, www.example.com unexpectedly closed the connection.

Это может быть потому, что:

  • Nginx не запущен. Вы можете проверить состояние Nginx с помощью sudo systemctl status nginx. Запустите Nginx с помощью sudo systemctl start nginx. Если Nginx не удается запустить, запустите sudo nginx -t, чтобы выяснить, нет ли ошибок в вашем конфигурационном файле. И проверьте логи (sudo journalctl -eu nginx), чтобы выяснить, почему он не запускается.
  • Брандмауэр блокирует порты 80 и 443. Если вы используете брандмауэр UFW на Debian/Ubuntu, выполните sudo ufw allow 80,443/tcp, чтобы открыть TCP порты 80 и 443. Если вы используете Firewalld на RHEL/CentOS/Rocky Linux/AlmaLinux, выполните sudo firewall-cmd –permanent –add-service={http,https}, затем sudo systemctl reload firewalld, чтобы открыть TCP порты 80 и 443.
  • Fail2ban. Если ваш сервер использует fail2ban для блокировки вредоносных запросов, возможно, fail2ban запретил ваш IP-адрес. Выполните команду sudo journalctl -eu fail2ban, чтобы проверить, не заблокирован ли ваш IP-адрес. Вы можете добавить свой IP-адрес в список fail2ban ignoreip, чтобы он больше не был забанен.
  • Nginx не прослушивает нужный сетевой интерфейс. Например, Nginx не прослушивает публичный IP-адрес сервера.

The Connection Has Timed Out

Это может означать, что ваш сервер находится в автономном режиме или Nginx работает неправильно.

Однажды у меня возникла проблема нехватки памяти, из-за чего Nginx не смог запустить рабочие процессы.

Если вы увидите следующее сообщение об ошибке в файле /var/log/nginx/error.log, вашему серверу не хватает памяти:

fork() failed while spawning "worker process" (12: Cannot allocate memory)

404 Not Found

404 not found означает, что Nginx не может найти ресурсы, которые запрашивает ваш веб-браузер.

🌐 Как создать пользовательскую страницу ошибки 404 в NGINX

Причина может быть следующей:

  • Корневой каталог web не существует на вашем сервере. В Nginx корневой веб-каталог настраивается с помощью директивы root, например, так: root /usr/share/nginx/linuxbabe.com/;. Убедитесь, что файлы вашего сайта (HTML, CSS, JavaScript, PHP) хранятся в правильном каталоге.
  • PHP-FPM не запущен. Вы можете проверить статус PHP-FPM с помощью sudo systemctl status php7.4-fpm (Debian/Ubuntu) или sudo systemctl status php-fpm.
  • Вы забыли включить директиву try_files $uri /index.php$is_args$args; в конфигурационный файл сервера Nginx. Эта директива необходима для обработки PHP-кода.
  • На вашем сервере нет свободного дискового пространства. Попробуйте освободить немного дискового пространства. Вы можете использовать утилиту ncdu (sudo apt install ncdu или sudo dnf install ncdu), чтобы узнать, какие каталоги занимают огромное количество дискового пространства.

403 Forbidden

Эта ошибка означает, что вам не разрешен доступ к ресурсам запроса.

Возможный сценарий включает:

  • Администратор сайта блокирует публичный доступ к запрашиваемым ресурсам с помощью белого списка IP-адресов или других методов.
  • На сайте может использоваться брандмауэр веб-приложения, например ModSecurity, который обнаружил атаку вторжения, поэтому заблокировал запрос.
    Некоторые веб-приложения могут показывать другое сообщение об ошибке, когда происходит запрет 403. Оно может сказать вам, что “secure connection failed, хотя причина та же.

500 Internal Server Error

Это означает, что в веб-приложении произошла какая-то ошибка.

Это может быть следующее

  • Сервер базы данных не работает. Проверьте состояние MySQL/MariaDB с помощью sudo systemctl status mysql. Запустите его с помощью sudo systemctl start mysql. Запустите sudo journalctl -eu mysql, чтобы выяснить, почему он не запускается. Процесс MySQL/MariaDB может быть завершен из-за проблем с нехваткой памяти.
  • Вы не настроили Nginx на использование PHP-FPM, поэтому Nginx не знает, как выполнять PHP-код.
  • Если ваше веб-приложение имеет встроенный кэш, вы можете попробовать очистить кэш приложения, чтобы исправить эту ошибку.
  • Ваше веб-приложение может создавать свой собственный журнал ошибок. Проверьте этот файл журнала, чтобы отладить эту ошибку.
  • Возможно, в вашем веб-приложении есть режим отладки. Включите его, и вы увидите более подробные сообщения об ошибках на веб-странице. Например, вы можете включить режим отладки в почтовом сервере хостинг-платформы Modoboa, установив DEBUG = True в файле /srv/modoboa/instance/instance/settings.py.
  • PHP-FPM может быть перегружен. Проверьте журнал PHP-FPM (например, /var/log/php7.4-fpm.log). Если вы обнаружили предупреждение [pool www] seems busy (возможно, вам нужно увеличить pm.start_servers, или pm.min/max_spare_servers), вам нужно выделить больше ресурсов для PHP-FPM.
  • Иногда перезагрузка PHP-FPM (sudo systemctl reload php7.4-fpm) может исправить ошибку.

Nginx показывает страницу по умолчанию

Если вы пытаетесь настроить виртуальный хост Nginx и при вводе доменного имени в веб-браузере отображается страница Nginx по умолчанию, это может быть следующее

  • Вы не использовали реальное доменное имя для директивы server_name в виртуальном хосте Nginx.
  • Вы забыли перезагрузить Nginx.

504 Gateway time-out

Это означает, что апстрим, такой как PHP-FPM/MySQL/MariaDB, не может обработать запрос достаточно быстро.

Вы можете попробовать перезапустить PHP-FPM, чтобы временно исправить ошибку, но лучше начать настраивать PHP-FPM/MySQL/MariaDB для более быстрой работы.

Вот конфигурация InnoDB в моем файле /etc/mysql/mariadb.conf.d/50-server.cnf.

Это очень простая настройка производительности.

innodb_buffer_pool_size = 1024M
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup  = ON
innodb_log_file_size = 512M
innodb_log_buffer_size = 8M

#Improving disk I/O performance
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 400
innodb_flush_method = O_DIRECT
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_buffer_pool_instances = 3

Где:

  • InnoDB buffer pool size должен быть не менее половины вашей оперативной памяти. (Для VPS с небольшим объемом оперативной памяти я рекомендую установить размер буферного пула на меньшее значение, например 400M, иначе ваш VPS будет работать без оперативной памяти).
  • InnoDB log file size должен составлять 25% от размера буферного пула.
  • Установите потоки ввода-вывода для чтения и записи на максимум (64).
  • Заставьте MariaDB использовать 3 экземпляра буферного пула InnoDB. Количество экземпляров должно соответствовать количеству ядер процессора в вашей системе.
  • После сохранения изменений перезапустите MariaDB.

После сохранения изменений перезапустите MariaDB.

sudo systemctl restart mariadb

Вы также можете установить более длительное значение тайм-аута в Nginx, чтобы уменьшить вероятность тайм-аута шлюза.

Отредактируйте файл виртуального хоста Nginx и добавьте следующие строки в блок server {…}.

  proxy_connect_timeout       600;
  proxy_send_timeout          600;
  proxy_read_timeout          600;
  send_timeout                600;

Если вы используете Nginx с PHP-FPM, то установите для параметра fastcgi_read_timeout большее значение, например 300 секунд.

По умолчанию это 60 секунд.

 location ~ \.php$ {
     try_files $uri /index.php$is_args$args;
     include snippets/fastcgi-php.conf;
     fastcgi_split_path_info ^(.+\.php)(/.+)$;

     fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     include fastcgi_params;
     fastcgi_read_timeout 300;
 }

Затем перезагрузите Nginx.

sudo systemctl reload nginx

PHP-FPM также имеет максимальное время выполнения для каждого скрипта.

Отредактируйте файл php.ini.

sudo nano /etc/php/7.4/fpm/php.ini

Вы можете увеличить это значение до 300 секунд.

max_execution_time = 300

Затем перезапустите PHP-FPM

sudo systemctl restart php7.4-fpm

Размер памяти исчерпан

Если вы видите следующую строку в журнале ошибок Nginx, это означает, что PHP достиг лимита памяти в 128 МБ.

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 57134520 bytes)

Вы можете отредактировать файл php.ini (/etc/php/7.4/fpm/php.ini) и увеличить лимит памяти PHP.

memory_limit = 512M

Затем перезапустите PHP7.4-FPM.

sudo systemctl restart php7.4-fpm

Если ошибка все еще существует, скорее всего, в вашем веб-приложении плохой PHP-код, который потребляет много оперативной памяти.

PR_END_OF_FILE_ERROR

  1. Вы настроили Nginx на перенаправление HTTP-запросов на HTTPS, но в Nginx нет блока сервера, обслуживающего HTTPS-запросы.
  2. Может быть, Nginx не запущен?
  3. Иногда основной бинарник Nginx запущен, но рабочий процесс может не работать и завершиться по разным причинам. Для отладки проверьте логи ошибок Nginx (/var/log/nginx/error.log).

Resource temporarily unavailable

Некоторые пользователи могут найти следующую ошибку в файле логов ошибок Nginx (в разделе /var/log/nginx/).

connect() to unix:/run/php/php7.4-fpm.sock failed (11: Resource temporarily unavailable)

Обычно это означает, что на вашем сайте много посетителей и PHP-FPM не справляется с обработкой огромного количества запросов.

Вы можете изменить количество дочерних процессов PHP-FPM, чтобы он мог обрабатывать больше запросов.

Отредактируйте файл PHP-FPM www.conf.

(Путь к файлу зависит от дистрибутива Linux).

sudo /etc/php/7.4/fpm/pool.d/www.conf

По умолчанию конфигурация дочернего процесса выглядит следующим образом:

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Приведенная выше конфигурация означает.

  • PHP-FPM динамически создает дочерние процессы. Нет фиксированного количества дочерних процессов.
  • Создается не более 5 дочерних процессов.
  • При запуске PHP-FPM запускаются 2 дочерних процесса.
  • Есть как минимум 1 незанятый процесс.
  • Максимум 3 неработающих процесса.
pm = dynamic
pm.max_children = 20
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 12

Убедитесь, что у вас достаточно оперативной памяти для запуска дополнительных дочерних процессов.

Сохраните и закройте файл.

Затем перезапустите PHP-FPM. (Возможно, вам потребуется изменить номер версии).

sudo systemctl restart php7.4-fpm

Чтобы следить за состоянием PHP-FPM, вы можете включить страницу status .

Найдите следующую строку в файле PHP-FPM www.conf.

Обратите внимание, что

;pm.status_path = /status

Уберите точку с запятой, чтобы включить страницу состояния PHP-FPM.

Затем перезапустите PHP-FPM.

sudo systemctl restart php7.4-fpm

Затем отредактируйте файл виртуального хоста Nginx.

Добавьте следующие строки.

Директивы allow и deny используются для ограничения доступа.

Только IP-адреса из “белого списка” могут получить доступ к странице состояния.

location ~ ^/(status|ping)$ {
        allow 127.0.0.1;
        allow your_other_IP_Address;
        deny all;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
        include fastcgi_params;
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_pass   unix:/run/php/php7.4-fpm.sock;
}

Сохраните и закройте файл. Затем протестируйте конфигурацию Nginx.

sudo nginx -t

Если проверка прошла успешно, перезагрузите Nginx, чтобы изменения вступили в силу.

sudo systemctl reload nginx

В файле PHP-FPM www.conf дается хорошее объяснение того, что означает каждый параметр.

Если PHP-FPM очень занят и не может обслужить запрос немедленно, он поставит его в очередь.

По умолчанию может быть не более 511 ожидающих запросов, определяемых параметром listen.backlog.

listen.backlog = 511

Если вы видите следующее значение на странице состояния PHP-FPM, это означает, что в очереди еще не было ни одного запроса, т.е. ваш PHP-FPM может быстро обрабатывать запросы.

listen queue:         0
max listen queue:     0

Если в очереди 511 ожидающих запросов, это означает, что ваш PHP-FPM очень загружен, поэтому вам следует увеличить количество дочерних процессов.

Вам также может понадобиться изменить параметр ядра Linux net.core.somaxconn, который определяет максимальное количество соединений, разрешенных к файлу сокетов в Linux, например, к файлу сокетов PHP-FPM Unix.

По умолчанию его значение равно 128 до ядра 5.4 и 4096 начиная с ядра 5.4.

$ sysctl net.core.somaxconn
net.core.somaxconn = 128

Если у вас сайт с высокой посещаемостью, вы можете использовать большое значение.

Отредактируйте файл /etc/sysctl.conf.

sudo nano /etc/sysctl.cnf

Добавьте следующие две строки.

net.core.somaxconn = 20000
net.core.netdev_max_backlog = 65535

Сохраните и закройте файл. Затем примените настройки.

sudo sysctl -p

Примечание: Если ваш сервер имеет достаточно оперативной памяти, вы можете выделить фиксированное количество дочерних процессов для PHP-FPM, как показано ниже.

Два файла виртуального хоста для одного и того же сайта

Если вы запустите sudo nginx -t и увидите следующее предупреждение.

nginx: [warn] conflicting server name "example.com" on [::]:443, ignored
nginx: [warn] conflicting server name "example.com" on 0.0.0.0:443, ignored

Это означает, что есть два файла виртуальных хостов, содержащих одну и ту же конфигурацию server_name.

Не создавайте два файла виртуальных хостов для одного сайта.

PHP-FPM Connection reset by peer

В файле логов ошибок Nginx отображается следующее сообщение.

recv() failed (104: Connection reset by peer) while reading response header from upstream

Это может быть вызвано перезапуском PHP-FPM.

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

Утечки сокетов Nginx

Если вы обнаружили следующее сообщение об ошибке в файле /var/log/nginx/error.log, значит, у вашего Nginx проблема с утечкой сокетов.

2021/09/28 13:27:41 [alert] 321#321: *120606 open socket #16 left in connection 163
2021/09/28 13:27:41 [alert] 321#321: *120629 open socket #34 left in connection 188
2021/09/28 13:27:41 [alert] 321#321: *120622 open socket #9 left in connection 213
2021/09/28 13:27:41 [alert] 321#321: *120628 open socket #25 left in connection 217
2021/09/28 13:27:41 [alert] 321#321: *120605 open socket #15 left in connection 244
2021/09/28 13:27:41 [alert] 321#321: *120614 open socket #41 left in connection 245
2021/09/28 13:27:41 [alert] 321#321: *120631 open socket #24 left in connection 255
2021/09/28 13:27:41 [alert] 321#321: *120616 open socket #23 left in connection 258
2021/09/28 13:27:41 [alert] 321#321: *120615 open socket #42 left in connection 269
2021/09/28 13:27:41 [alert] 321#321: aborting

Вы можете перезапустить ОС, чтобы решить эту проблему.

Если это не помогает, вам нужно скомпилировать отладочную версию Nginx, которая покажет вам отладочную информацию в логах.

Заключение

Надеюсь, эта статья помогла вам исправить распространенные ошибки веб-сервера Nginx.

см. также:

 

Добавить комментарий