Ошибка Nginx: «Сайт недоступен»

Вопрос или проблема

Я управляю платформой управления школой на базе PHP 8.2 и Symfony 7, размещенной на VPS с 16 ГБ ОЗУ от Hostinger, работающей на Ubuntu и Nginx. Мое приложение — это традиционный сайт с серверной отрисовкой без динамического фронтенд-фреймворка.

Вот ситуация:
Когда пользователь инициирует действие, которое обрабатывает большой объем данных в базе данных, например, создавая табели успеваемости для целого класса из 60 учеников, или генерируя статистику класса, страница отображает ошибку “Невозможно подключиться к сайту” примерно через 30 секунд.

Наблюдения:

  1. Когда массовые данные обрабатываются в очереди, например, с использованием Symfony Messenger, процесс проходит безупречно, даже для более 1000.
  2. Если я сегментирую обработку данных, например, генерируя табели по 10 учеников за раз, процесс завершается быстро и без ошибок.
  3. В моей локальной среде разработки (Windows 10 с Apache, 8 ГБ ОЗУ) те же задачи выполняются успешно, независимо от размера данных (например, создание табелей или статистики для целого класса из 60 или более чем 120 учеников). Даже если процесс занимает от 1 до 10 минут или больше, он в конечном итоге генерирует ожидаемые результаты.

Я пытался отладить, когда возникала ошибка

  1. Отладка с помощью команды **free -h** при генерации табелей:
    описание изображения здесь

  2. Отладка с помощью команды htop при генерации табелей:
    описание изображения здесь

Вот журналы

  1. sudo cat /var/log/nginx/error.log
    описание изображения здесь
  2. sudo grep “500” /var/log/nginx/access.log
    описание изображения здесь

Что я пробовал

  1. Увеличение лимита php в php.ini из /etc/php/8.2/fpm/php.ini
  • memory_limit=-1
  • maximum_time_execution = 3600
  • post_max_size = 100M
  • upload_max_filesize = 100M
  1. Обновление конфигурации nginx из /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 1024;
        # multi_accept on;
}

http {
        # Глобальные таймауты
        proxy_read_timeout 300s;  # Время ожидания для прокси
        fastcgi_read_timeout 300s; # Время ожидания для FastCGI
        client_max_body_size 100M;
        client_body_timeout 300s;
        client_header_timeout 300s;
        keepalive_timeout 300s;
        send_timeout 300s;
 ....
} ...
  1. Вот моя конфигурация mysql
#
# Файл конфигурации сервера базы данных MySQL.
#
# Можно использовать все длинные опции, которые поддерживает программа.
# Запустите программу с --help, чтобы получить список доступных опций, и с
# --print-defaults, чтобы увидеть, какие из них она реально понимает и использует.
#
# Для объяснений см. http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# Здесь представлены записи для некоторых конкретных программ
# Следующие значения предполагают, что у вас как минимум 32M ОЗУ

[mysqld]
#
# * Основные настройки
#
user            = mysql
# pid-file      = /var/run/mysqld/mysqld.pid
# socket        = /var/run/mysqld/mysqld.sock
# port          = 3306
# datadir       = /var/lib/mysql

# Если MySQL работает в качестве репликационного слейва, это следует
# изменить. Смотрите https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir
# tmpdir                = /tmp
#
# Вместо отключения сетевых функций, по умолчанию используется прослушивание только на
# localhost, что более совместимо и не менее безопасно.
bind-address            = 127.0.0.1
mysqlx-bind-address     = 127.0.0.1

#
# * Тонкая настройка
#
#
innodb_buffer_pool_size = 6G
#innodb_log_file_size = 512M
innodb_redo_log_capacity = 1G
innodb_flush_log_at_trx_commit = 2
innodb_io_capacity = 1000

# Настройка памяти и производительности
key_buffer_size         = 64M
max_allowed_packet      = 128M
thread_stack            = 256K
thread_cache_size       = 8

# Кэш таблиц
table_open_cache        = 2000

# Соединения
max_connections         = 500
#wait_timeout = 3600
#innodb_lock_wait_timeout = 3600

# Временные таблицы
tmp_table_size          = 64M
max_heap_table_size     = 64M
# Временные таблицы
tmp_table_size          = 64M
max_heap_table_size     = 64M

# Опции восстановления MyISAM
myisam-recover-options  = BACKUP

#
# * Логирование и репликация
#
# Оба местоположения поворачиваются кроновой задачей.
#
# Логирование всех запросов
# Учтите, что этот тип лога может снижать производительность.
# general_log_file        = /var/log/mysql/query.log
# general_log             = 1

# Файл журнала ошибок — должен содержать очень мало записей.
log_error = /var/log/mysql/error.log

# Здесь можно увидеть запросы с особенно долгим временем выполнения
# slow_query_log          = 1
# slow_query_log_file     = /var/log/mysql/mysql-slow.log
# long_query_time         = 2
# log-queries-not-using-indexes

# Следующие параметры могут использоваться как легкие для воспроизведения резервные копии или для репликации.
# примечание: если вы настраиваете репликационный слейв, смотрите README.Debian для
# других настроек, которые могут потребоваться изменить.
# server-id               = 1
# binlog_expire_logs_seconds = 2592000
max_binlog_size          = 100M
# binlog_do_db            = include_database_name
# binlog_ignore_db        = include_database_name 
  1. Я также пробовал это для PHP-FPM Wokers в /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10

Резюме проблемы:

  • У меня есть локальная среда, отличная от производственной.
  • Моя локальная среда — это Windows 10 + Apache + 8 ГБ ОЗУ, а моя производственная среда — Ubuntu 22 + Nginx + 16 ГБ ОЗУ.
  • Моя локальная среда, менее мощная, чем производственная (локальная: 8 ГБ ОЗУ, прод: 16 ГБ ОЗУ) может сгенерировать 60 или 120 и более табелей, даже если это займет время, и если возникнет таймаут, он отобразится как явное сообщение о таймауте, а не “Невозможно подключиться к сайту” в браузере.
  • Моя производственная машина с 16 ГБ ОЗУ и настройками на Ubuntu показывает в браузере “Невозможно подключиться к сайту” после примерно 30 секунд, когда я пытаюсь выполнить ту же задачу, которая работает на моей локальной машине, которая менее мощная.
  • Я не знаю, является ли проблема таймаутом nginx или чем-то другим, потому что я попытался увеличить таймаут nginx, но проблема осталась той же.
  • На сервере, где возникает проблема, система очередей работает корректно, но обработка больших объемов данных в базе данных с повторной загрузкой страниц не работает должным образом.

Любая помощь или предложение помогут. Заранее спасибо.

Ответ или решение

Проблема, с которой вы столкнулись, связана с ошибкой "Этот сайт недоступен", возникающей при загрузке страниц после обработки большого объема данных в базе данных на вашем сервере с помощью Nginx. Давайте разберем возможные причины и способы их решения.

Теория:

Ошибка "Этот сайт недоступен" обычно возникает, когда сервер не может обработать запрос в установленный лимит времени, и соединение разрывается. В вашем случае время до возникновения ошибки составляет около 30 секунд. Это может быть связано с настройками timeout, установленными на вашем сервере.

Ваш локальный сервер на Windows под Apache не имеет такой проблемы, что говорит о различиях в окружающей среде и конфигурациях между вашим локальным и продакшн-серверами. Основные различия включают различия в обработке запросов между Nginx и Apache, а также в стандартных настройках этих серверов.

Пример:

На вашем продакшн-сервере используются настройки Nginx, которые могут иметь наследственные короткие таймауты для состояния соединения, такие как proxy_read_timeout, fastcgi_read_timeout, и другие. Несмотря на то, что вы уже повысили значения для таймаутов в конфигурации Nginx, проблема осталась. Это может указывать на нерассмотренные аспекты, такие как сетевые настройки или настройки на уровне браузера.

Кроме того, использование Symfony Messenger и успешное выполнение заданий в очереди подтверждает, что проблема именно в обработке запросов через HTTP, а не в способности сервера справляться с обработкой данных.

Применение:

  1. Проверьте таймауты на уровне браузера: В некоторых браузерах стандартный таймаут для ожидания ответа от сервера может быть установлен в 30 секунд. Попробуйте использовать другие браузеры или изменить настройки на этих уровнях для тестирования.

  2. Дополнительная оптимизация PHP и Nginx:

    • Убедитесь, что вы увеличили request_terminate_timeout в конфигурации PHP-FPM, чтобы избежать преждевременного завершения обработки скриптов.
    • Перепроверьте все уровни таймаута в конфигурации Nginx, включая proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout, чтобы убедиться, что они соответствуют увеличенной длительности выполнения скриптов.
  3. Используйте асинхронную обработку или генерацию страниц: Разделение обработки данных на меньшие части или улучшение асинхронных операций, где это возможно, может значительно снизить время ожидания для пользователя.

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

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

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

Капча загружается...