5.5 KiB
Кейс: Nginx как reverse proxy и балансировщик нагрузки
Связь с легендой: ../../legend/LEGEND.md — раздел «АО ТНИИС», конфигурационные файлы Nginx для маршрутизации и балансировки нагрузки перед сервисами.
Что нужно реально сделать (домашний стенд)
Поднять два бэкенд-сервиса и один Nginx перед ними, который распределяет нагрузку и отдаёт статус бэкендов, чтобы своими руками увидеть балансировку, health-check-подобное поведение и базовую защиту (rate limiting).
1. Структура
nginx-lab/
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
└── backend/
└── index.html
2. docker-compose.yml
version: "3.8"
services:
backend1:
image: nginx:alpine
container_name: backend1
volumes:
- ./backend/index.html:/usr/share/nginx/html/index.html
environment:
- INSTANCE=backend1
backend2:
image: nginx:alpine
container_name: backend2
volumes:
- ./backend/index.html:/usr/share/nginx/html/index.html
environment:
- INSTANCE=backend2
proxy:
image: nginx:alpine
container_name: proxy
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "8080:80"
depends_on:
- backend1
- backend2
3. nginx/nginx.conf
events {
worker_connections 1024;
}
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=5r/s;
upstream backend_pool {
least_conn;
server backend1:80 max_fails=3 fail_timeout=10s;
server backend2:80 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
location / {
limit_req zone=req_limit burst=10 nodelay;
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /health {
return 200 'ok';
add_header Content-Type text/plain;
}
}
}
4. Шаги воспроизведения
docker compose up -d.curl http://localhost:8080/несколько раз подряд — убедиться, что ответы приходят от backend1 и backend2 попеременно (балансировкаleast_conn; чтобы увидеть разницу в теле ответа, положить вindex.htmlразные значения черезINSTANCEили просто проверить по логамdocker compose logs backend1 backend2, какой контейнер получил запрос).- Остановить один бэкенд (
docker compose stop backend1) и убедиться, что Nginx продолжает отдавать 200, перенаправляя весь трафик на backend2 — практикаmax_fails/fail_timeoutв деле. - Прогнать быстрый цикл запросов (
for i in $(seq 1 20); do curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/; done) и увидеть503отlimit_req, когда запросы превышаютrate=5r/s— понять, как работает rate limiting на практике. - Проверить
curl http://localhost:8080/health— отдельный location без проксирования, как обычно делают health-check эндпоинт.
5. Что это даёт в разговоре с интервьюером
- Понимание
upstream-блока и алгоритмов балансировки (round-robinпо умолчанию,least_conn,ip_hash). - Понимание, зачем нужны
proxy_set_header(чтобы бэкенд видел реальный IP и Host клиента, а не адрес самого Nginx). - Практика rate limiting (
limit_req_zone/limit_req) как базовой защиты от перегрузки/abuse. - Понимание
max_fails/fail_timeoutкак механизма пассивного health-check upstream-серверов.
Нагрузка и цифры
Замерить пропускную способность своего стенда: hey -n 10000 -c 50 http://localhost:8080/ (или wrk -t2 -c50 -d30s http://localhost:8080/) — записать полученный RPS и задержку p50/p99. Сравнение с публичными ориентирами по nginx (десятки тысяч RPS на статике, тысячи на проксировании — сильно зависит от конфигурации) и таблица для собственных замеров — в ../../legend/CAPACITY.md.
Как это ложится в легенду
В реальной работе (АО ТНИИС) — конфиги Nginx для маршрутизации и балансировки перед сервисами, в том числе перед компонентами мониторинга. Домашний кейс воспроизводит тот же принцип на двух простых бэкендах вместо реального внутреннего сервиса.