Nginx
Что это такое
Nginx — это веб-сервер, который чаще всего развёртывают как обратный прокси: он принимает соединения от клиентов и передаёт их одному или нескольким приложениям позади себя. В этой роли он отдаёт статические файлы напрямую, завершает TLS, распределяет запросы по нескольким бэкендам и скрывает от внешнего мира настоящую топологию приложения. Это часть инфраструктуры, стоящая между интернетом и всем остальным.
Почему это важно
Почти в каждой продакшен-системе есть что-то на этой позиции, и понимание роли делает конфигурацию читаемой, а отказы — диагностируемыми. Обратный прокси — это то место, где действительно происходят ограничения соединений, тайм-ауты, буферизация и переписывание заголовков; поэтому удивительная доля инцидентов на сайте — обрезанная загрузка, медленный ответ без следа в источнике, клиент, видящий не ту схему, — на самом деле конфигурация прокси. Это ещё и самое дешёвое место добавить TLS, сжатие и статическое кэширование, не трогая код приложения.
Ключевые идеи
Соединение принимает прокси, а не приложение
Приложение за прокси может быть простым и медленно запускаться, потому что прокси держит соединение с клиентом, обслуживает медленного клиента в быстрой сети и даёт бэкенду ограниченный объём работы. Это разделение и есть причина существования такой схемы: обращённая к интернету забота и бизнес-логика разделены, и каждую можно масштабировать и заменять независимо.
клиент -> nginx (TLS, статические файлы, лимиты) -> серверы приложения
TLS завершается здесь, и это решает, какой будет схема
Шифрование на прокси означает, что сертификаты управляются в одном месте, а бэкенд говорит по простому HTTP внутри доверенной сети. Следствие, которое надо помнить: приложение видит обычный HTTP-запрос и может сгенерировать незащищённый адрес, если прокси не передаёт исходную схему и хост в заголовках. Отсюда классические проблемы смешанного содержимого и цикла перенаправлений.
Балансировка нагрузки — это выбор политики
Запросы можно распределять по кругу, по наименьшему числу соединений, по хешу какого-то ключа или с весами и переключением при отказе. Хеш удерживает клиента на одном бэкенде, что помогает, когда бэкенд хранит состояние сессии, и вредит, когда он падает. Осознанный выбор и решение о том, что происходит с нездоровым бэкендом, — вот что не даёт балансировке стать случайностью.
Буферизация и тайм-ауты решают судьбу загрузок и долгих запросов
Прокси может буферизовать тело запроса и ответ, прежде чем передать их дальше, что защищает медленный бэкенд от медленного клиента. Это также значит, что большая загрузка пишется на диск, а тайм-ауты запроса и ответа действуют на прокси, даже если приложение готово ждать дольше. Большинство сообщений «загрузка падает ровно на первой минуте» — это одна из таких настроек.
Статические файлы отдаются, не будя приложение
Прокси, отдающий изображения, таблицы стилей и загрузки напрямую, полностью убирает этот трафик из приложения. Это ещё и естественное место для заголовков кэширования и сжатия. То же верно для эндпоинтов проверки работоспособности, которыми пользуется балансировщик выше по потоку, — поэтому их часто отвечают прямо на прокси.
Это ещё и точка политики
Правила доступа, ограничения размера запроса и ограничение частоты живут здесь, до того как выполнится хоть строка кода приложения. Это делает прокси действенным местом, чтобы притупить грубую атаку или вышедшего из-под контроля клиента. Но это не замена безопасности на уровне приложения: корректно сформированный запрос, злоупотребляющий бизнес-логикой, проходит сквозь нетронутым.
Практика
Отдайте статический сайт через прокси
Поместите статический каталог за прокси, а приложение — за путём, и убедитесь, что статические файлы отдаются, не доходя до бэкенда.
Готово, когда: в логах приложения нет запроса по статическому пути, а ответ несёт заголовок кэширования прокси.
Проследите тайм-аут, вызванный прокси
Настройте тайм-аут запроса короче обычного времени ответа приложения, затем отправьте медленный запрос и прочитайте ответ, который клиент действительно получает.
Готово, когда: вы можете назвать настройку, вызвавшую этот ответ, и улику в логе прокси, которая её опознаёт.
Частые ошибки
- Не передавать исходную схему и хост бэкенду — приложение генерирует неверные адреса, и перенаправления зацикливаются; исправить: передавайте заголовки схемы и хоста и доверяйте им только от прокси.
- Оставить ограничение размера тела запроса по умолчанию — большая загрузка отвергается с непонятной ошибкой; исправить: задайте предел под то, что ожидает приложение.
- Балансировать по хешу, ожидая переключения при отказе — клиенты остаются прикреплёнными к упавшему бэкенду; исправить: выбирайте политику осознанно и определите поведение при нездоровом бэкенде.
- Считать прокси единственным средством безопасности — валидные запросы, злоупотребляющие бизнес-логикой, проходят; исправить: сохраняйте авторизацию и валидацию на уровне приложения.
- Игнорировать тайм-ауты прокси, когда запрос законно долгий — клиента обрывают, пока бэкенд продолжает работать; исправить: согласуйте тайм-ауты прокси с реальным временем ответа приложения.
Что читать дальше
- Основы сетей (HTTP / DNS / TLS) (06-cloud-devops/10-networking-fundamentals-http-dns-tls) — протоколы, которые этот прокси завершает и пересылает, поэтому читайте первым.
- CI/CD (06-cloud-devops/08-ci-cd) — как изменение конфигурации прокси тестируется и выпускается вместе с приложением, которое он обслуживает.
- Docker (06-cloud-devops/06-docker) — распространённый способ упаковать прокси и его бэкенды и запускать их вместе.