Вопрос или проблема
Я получаю ошибку 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.
Приложение
Чтобы устранить эту проблему и добиться наиболее плавного протекания запросов между клиентом и сервером, рекомендуется рассмотреть следующие меры:
-
Проверка таймаутов на всех уровнях: Убедитесь, что таймауты proxy и серверных процессов согласованы с таймаутами на любой промежуточной аппаратуре или программном обеспечении (например, брандмауэры или дополнительные прокси-серверы).
- Проверьте и увеличьте клиентские и проксированные таймауты в конфигурациях на стороне клиента и всех промежуточных прокси.
-
Мониторинг использования ресурсов: Используйте инструменты мониторинга для выяснения профиля загрузки CPU и использования памяти вашего сервера, чтобы убедиться, что все ресурсы эффективно распределяются.
-
Оптимизация Django-приложения: Проведите аудит кода Django. Предотвратите долгосрочные операции в запросах, перераспределив их в фоновые задачи.
-
Улучшение обработки сессий и кеширования: Убедитесь в правильности конфигурации сессий и кеширования, чтобы избежать задержек, вызванных длительным ожиданием завершения операций записи или чтения из базы данных.
-
Переосмысление архитектуры: Если ваше приложение обработывает долго работающие задачи, рассмотрите использование очередей задач (например, Celery) для асинхронной обработки длительных операций во избежание истечений времени при ответе HTTP.
-
Обратная связь и тестирование: Анализируйте логи запросов и ошибок, чтобы собрать больше данных о том, когда и как именно возникают проблемы. Проведите нагрузочные тесты, чтобы воспроизвести проблему и валидировать потенциальные решения.
Заключение
Как IT-эксперт, распознавание, диагностика и устранение причины ошибки типа 499 требует внимания к каждому компоненту, взаимодействующему в системе. Поскольку проблема может иметь различные корни, необходимо тщательно тестировать каждый аспект конфигурации и приложения, чтобы прийти к оптимальному решению. Акцент на комплексный аудит системных ресурсов, а также учет всех клиентских взаимодействий с инфраструктурой, предоставит наиболее полное понимание проблемы и позволит разработать устойчивую архитектуру приложения, устойчивую к подобным поведениям.