Пройти курс на Stepik
Главная/Материалы

Зачем нужен Nginx, если приложение само умеет принимать запросы

Логичный вопрос: приложение умеет слушать порт и отвечать на HTTP-запросы само. Зачем перед ним ставят ещё одну программу? Разберём, что она берёт на себя и почему именно в ней вы будете искать следы половины инцидентов.

Что произойдёт, если убрать

Проще начать с обратного. Пусть приложение принимает запросы напрямую.

Первая же проблема — сертификат. Шифрование придётся настраивать внутри приложения, и в каждом следующем сервисе заново. Сертификаты истекают, их нужно обновлять, и теперь это забота десяти разных команд вместо одной.

Вторая — масштабирование. Пока экземпляр приложения один, всё работает. Как только нужно два, возникает вопрос, кто и по какому принципу распределяет запросы между ними.

Третья — статика. Картинки, стили и скрипты будет отдавать само приложение, тратя на это ресурсы, которые предназначались для бизнес-логики.

Четвёртая — все остальные запросы приходят прямо в приложение: и поисковые роботы, и сканеры уязвимостей, и любители подобрать пароль перебором. Фильтровать их тоже придётся коду.

Nginx — это программа, которую ставят перед приложением, чтобы снять с него все четыре задачи разом. Работает она как обратный прокси: принимает запрос от пользователя, передаёт внутрь, забирает ответ, возвращает обратно. Снаружи видно только её.

Что он делает

Терминирует шифрование. Соединение по HTTPS устанавливается с nginx, а дальше внутри сети запрос идёт по обычному HTTP. Сертификат лежит в одном месте, приложения о нём ничего не знают.

Балансирует нагрузку. Запросы распределяются между несколькими экземплярами приложения. Если один перестал отвечать, nginx перестаёт слать на него трафик — пользователь при этом ничего не заметит.

Отдаёт статику. Файлы, которые не меняются, уходят пользователю напрямую с диска, минуя приложение.

Кэширует. Ответы, одинаковые для всех, сохраняются и отдаются из памяти без обращения к приложению.

Ограничивает и фильтрует. Здесь настраиваются лимиты на частоту запросов с одного адреса, белые и чёрные списки, ограничение размера загружаемого файла, блокировка по географии.

Маршрутизирует. По адресу запроса решает, в какой именно сервис его направить: запросы на /api/ — в одно приложение, всё остальное — в другое.

Главное для поддержки: access-лог

Поскольку nginx встречает запрос первым, именно здесь пишется самая полная картина внешнего трафика — access-лог. Это основной источник ответа на вопрос «что вообще происходило».

В стандартной строке лога есть адрес клиента, время с точностью до секунды, метод и путь запроса, код ответа, размер ответа, реферер и User-Agent. Почти всегда в формат добавляют ещё время обработки запроса — и это самое ценное поле, потому что по нему видно не только что сломалось, но и что начало тормозить.

Что с этим делать при разборе заявки:

Последний пункт стоит запомнить отдельно — он экономит часы. Разбирая ошибку, всегда полезно сначала понять, кто ответил: приложение или то, что стоит перед ним.

Ошибки, которые отдаёт сам nginx

Несколько кодов почти всегда означают, что проблема не в коде приложения:

502 Bad Gateway — nginx не смог получить ответ от приложения. Приложение не запущено, упало, слушает не тот порт или перезапускается прямо сейчас.

504 Gateway Timeout — приложение ответило, но слишком долго, и nginx не стал ждать. Обычно это тяжёлый запрос в базу, зависшая интеграция или таймаут, выставленный меньше реального времени обработки. Разница с 502 принципиальна: там связи не было вовсе, здесь связь была, но ответ не успел.

413 Request Entity Too Large — пользователь пытается загрузить файл крупнее разрешённого лимита. Классическая заявка «не загружается скан договора» решается одной строкой в конфигурации, а не доработкой приложения.

403 Forbidden от nginx — сработало ограничение по адресу, список доступа или права на файл. Отличить от 403 приложения легко: у nginx это простая HTML-страница, у приложения обычно JSON.

499 — нестандартный код, который nginx записывает, когда клиент закрыл соединение, не дождавшись ответа. В логах выглядит тревожно, но означает лишь, что пользователю надоело ждать и он обновил страницу. Массовые 499 — косвенный признак того, что сервис тормозит.

Практический вывод

Схема «пользователь → nginx → приложение» кажется очевидной, пока не начинаешь разбирать инцидент. Тогда выясняется, что каждый переход в этой цепочке — отдельная точка отказа, и первый вопрос при разборе всегда один: докуда запрос дошёл.

Ответ на него почти всегда лежит в access-логе, и поэтому доступ к нему стоит попросить раньше, чем он понадобится.

Все материалы
Пройти курс на Stepik