nginx, gunicorn, Django ошибка 499 через 60 секунд

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

Я получаю ошибку 499 через 60 секунд, независимо от конфигурации, которую я пробую. Я использую Docker на сервере с 8 ядрами и 32 ГБ оперативной памяти, и перед ним есть другой nginx/lets-encrypt реверс-прокси для других контейнеров. Я больше на стороне разработки. Я предполагаю, что мне нужно запускать пакет в фоновом режиме и собираюсь исследовать это, если не могу исправить это, но мне нужно понять эту ошибку.

gunicorn worker, кажется, работает после ошибки:

[2019-06-01 17:49:31 +0000] [1] [INFO] Прослушивание на: http://0.0.0.0:8000 (1)
[2019-06-01 17:49:31 +0000] [1] [INFO] Используется рабочий: threads
[2019-06-01 17:49:31 +0000] [9] [INFO] Запуск рабочего с pid: 9
[2019-06-01 17:49:31 +0000] [10] [INFO] Запуск рабочего с pid: 10
[2019-06-01 17:49:31 +0000] [11] [INFO] Запуск рабочего с pid: 11
[2019-06-01 17:49:31 +0000] [12] [INFO] Запуск рабочего с pid: 12
[2019-06-01 17:49:31 +0000] [13] [INFO] Запуск рабочего с pid: 13
[2019-06-01 17:49:31 +0000] [14] [INFO] Запуск рабочего с pid: 14
[2019-06-01 17:49:31 +0000] [15] [INFO] Запуск рабочего с pid: 15
[2019-06-01 17:49:31 +0000] [16] [INFO] Запуск рабочего с pid: 16

Версия nginx: nginx/1.15.12

gunicorn 19.9.0

Django 2.2.1

конфигурация nginx

upstream cobalt {
  server cobalt:8000;
}

# Захват всех запросов с недопустимым заголовком HOST
server {
    server_name "";
    listen      8000;
    return      444;
}

# портал
server {
    listen 8000;
    server_name xxxxxxxx;

    location / {
        proxy_set_header Host $host;
        proxy_pass http://cobalt;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection "";
        proxy_connect_timeout 1200s;
        proxy_read_timeout 1200s;
        proxy_send_timeout 1200s;
        client_max_body_size 100M;
        client_body_buffer_size 100M;
        client_body_timeout 1200s;
        keepalive_timeout 1200s;
        send_timeout 1200s;
        uwsgi_read_timeout 1200s;
    }

    location /static/ {
        autoindex on;
        alias /static/;
    }

    location /private-x-accel-redirect/ {
        internal;
        alias   /media/;
    }

}

конфигурация gunicorn

"""конфигурация сервера gunicorn WSGI."""
bind = '0.0.0.0:8000'
timeout = 1200
workers = 8
threads = 2

Решили ли вы эту проблему? У меня та же проблема, и я не имею представления, что вызывает эту ошибку 499. Я сконфигурировал свой сервер и все остальное так же, как и вы.

ИЗМЕНЕНИЕ 1: Привет, ребята, я нашел источник этой проблемы в МОЕМ СЛУЧАЕ. По какой-то причине сохранение информации в сессии: django.session[‘value1’] = ‘value2’ вызывает эту ошибку. Я удалил django.session для теста и все работает отлично. Я еще не нашел решение, но как только решу эту проблему, обновлю здесь.

ИЗМЕНЕНИЕ 2: Я решил проблему, в моем случае база данных из AWS RDS не могла быть доступна, потому что я что-то испортил. Я пересоздал базу данных, и теперь все работает отлично.

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

Ошибка 499 в Nginx указывает на то, что клиент (обычно веб-браузер) закрыл соединение до того, как сервер успел ответить. Эта ошибка специфична для Nginx и обычно возникает, когда сервер долго не отвечает на запросы. В вашем случае, проблема заключается в задержке, происходящей, вероятно, по ряду причин в ядре вашего стека: Nginx, Gunicorn и Django.

Теория

Абсолютно необходимо понимать, что ваша система развернута с двумя уровнями обратного прокси (reverse proxy): один для управления let’s encrypt и другой для обработки запросов, поступающих к вашим контейнерам Docker. В стеке, который использует Docker, Gunicorn и Django, обычно Nginx выступает как передний обработчик, передающий запросы к Gunicorn, который в свою очередь взаимодействует с Django-приложением.

Ошибка Nginx 499 свидетельствует о завершении клиентом соединения прежде, чем сервер смог обработать запрос полностью. Это может быть вызвано рядом причин:

  • Таймауты: Основная причина, предлагаемая вашими путями решения проблемы. Клиент (или прокси-сервер между клиентом и вашим сервером) может быть настроен на таймаут в 60 секунд, в то время как ваш сервер настроен на длительные периоды ожидания.
  • Ресурсы сервера: Несмотря на то что у вашего сервера 8 ядер и 32 ГБ памяти, сам контейнер или приложением может быть настроено на использование меньших ресурсов, что приводит к задержкам.
  • Сложные запросы: Если ваш код в Django обрабатывает комплексные запросы, которые используют много ресурсов, это может также создать задержки.
  • Неправильное кеширование или сессии: Как вы заметили, использование сессий может иногда быть причиной ошибок, если система управления сессией или доступа к базе данных работает неправильно.

Пример

На основе предоставленного описания конфигурации Nginx и Gunicorn вы, вероятно, уже предприняли шаги для увеличения таймаутов до 1200 секунд. Очевидно, это должно было бы помочь, если бы проблема заключалась исключительно в таймаутах уровня сервера. Однако клиентская сторона (брандмауэр, обратный прокси или даже сам пользователь) также может иметь свои собственные ограничения по времени ожидания.

Если клиент не получает ответа от сервера в течение времени, установленного в его настройках, он может прервать соединение, что и приводит к ошибке 499.

Приложение

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

  1. Проверка таймаутов на всех уровнях: Убедитесь, что таймауты proxy и серверных процессов согласованы с таймаутами на любой промежуточной аппаратуре или программном обеспечении (например, брандмауэры или дополнительные прокси-серверы).

    • Проверьте и увеличьте клиентские и проксированные таймауты в конфигурациях на стороне клиента и всех промежуточных прокси.
  2. Мониторинг использования ресурсов: Используйте инструменты мониторинга для выяснения профиля загрузки CPU и использования памяти вашего сервера, чтобы убедиться, что все ресурсы эффективно распределяются.

  3. Оптимизация Django-приложения: Проведите аудит кода Django. Предотвратите долгосрочные операции в запросах, перераспределив их в фоновые задачи.

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

  5. Переосмысление архитектуры: Если ваше приложение обработывает долго работающие задачи, рассмотрите использование очередей задач (например, Celery) для асинхронной обработки длительных операций во избежание истечений времени при ответе HTTP.

  6. Обратная связь и тестирование: Анализируйте логи запросов и ошибок, чтобы собрать больше данных о том, когда и как именно возникают проблемы. Проведите нагрузочные тесты, чтобы воспроизвести проблему и валидировать потенциальные решения.

Заключение

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

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

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