Лабораторная: диагностика Nginx 502/504¶
В паре со статьёй: Обратный прокси Nginx и диагностика 502/504
Окружение: одна одноразовая VM с установленным nginx и доступным Python 3 (для простейшего backend). Если вы предпочитаете контейнеры вместо VM, файлы ниже воспроизводят ту же лабораторную.
Версия лабораторной на Docker Compose (необязательно)
# docker-compose.yml
services:
nginx:
image: nginx:1.27-alpine
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- backend
backend:
image: python:3.12-alpine
command: python3 -m http.server 8000
# nginx.conf (next to docker-compose.yml)
upstream app_backend {
server backend:8000;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 5s;
}
}
Чтобы воспроизвести сценарий 502, выполните docker compose stop backend; чтобы вернуть всё обратно — docker compose start backend.
Начальные условия¶
- nginx установлен и работает.
- Конфигурация обратного прокси из родительской статьи, указывающая на
127.0.0.1:8000. - Простейший backend запущен и подтверждена доступность через nginx: Это должно вернуть
HTTP/1.1 200 OK.
Инструкции¶
Часть 1 — Получите 502¶
- Остановите backend:
kill %1(или найдите его PID черезjobs -l/pgrep -f http.serverи завершите его). - Выполните
curl -i http://localhost/и понаблюдайте за ответом. - Проверьте самую новую запись в
/var/log/nginx/error.log.
Часть 2 — Получите 504¶
- Перезапустите backend, но на этот раз сделайте его искусственно медленным (симуляция зависшего запроса):
- Установите короткий
proxy_read_timeout 5s;в конфиге nginx (временно, для этого теста) и перезагрузите nginx. - Выполните
curl -i http://localhost/и замерьте время до получения ответа.
Ожидаемые результаты¶
- Часть 1:
curlполучаетHTTP/1.1 502 Bad Gatewayпрактически мгновенно (без ожидания — nginx сразу знает, что соединение было отказано). Лог ошибок показываетconnect() failed (111: Connection refused)со ссылкой на127.0.0.1:8000. - Часть 2:
curlждёт примерно 5 секунд (соответствуетproxy_read_timeout), а затем получаетHTTP/1.1 504 Gateway Timeout— заметно не мгновенно, и не полные 90 секунд, которые backend в итоге потратил бы на ответ.
Чек-лист диагностики¶
- [ ] Подтвердили ли вы, что 502 был мгновенным (сбой на уровне соединения) против 504, задержанного примерно на настроенный таймаут (ответ, который просто не пришёл вовремя)?
- [ ] Проверили ли вы
error.logдля части 1 и правильно интерпретировалиConnection refusedкак «ничего не слушает», отличая это от сброса соединения или таймаута? - [ ] Для части 2: подтвердили ли вы прямым
curlк127.0.0.1:8000, минуя nginx полностью, что именно сам backend медленный (а не что-то не так конкретно на участке nginx→backend)?
Критерии успеха¶
Вы можете объяснить для любого будущего 502 или 504 в вашем собственном продакшн-nginx, в какую из этих двух категорий он попадает и какой должна быть ваша следующая диагностическая команда — без необходимости перечитывать родительскую статью.
Очистка / откат¶
# Остановить любой зависший тестовый backend:
pkill -f http.server
# Откатить временный proxy_read_timeout, если меняли:
sudo sed -i 's/proxy_read_timeout 5s;/proxy_read_timeout 60s;/' /etc/nginx/sites-available/app.conf
sudo nginx -t && sudo systemctl reload nginx
Убедитесь, что curl -i http://localhost/ снова возвращает нормальный 200 OK (с реально работающим backend), прежде чем считать окружение восстановленным.