Files
resume/stack/nginx/CASE.md

112 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Кейс: Nginx как reverse proxy и балансировщик нагрузки
Связь с легендой: [../../legend/LEGEND.md](../../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
```yaml
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
```nginx
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. Шаги воспроизведения
1. `docker compose up -d`.
2. `curl http://localhost:8080/` несколько раз подряд — убедиться, что ответы приходят от backend1 и backend2 попеременно (балансировка `least_conn`; чтобы увидеть разницу в теле ответа, положить в `index.html` разные значения через `INSTANCE` или просто проверить по логам `docker compose logs backend1 backend2`, какой контейнер получил запрос).
3. Остановить один бэкенд (`docker compose stop backend1`) и убедиться, что Nginx продолжает отдавать 200, перенаправляя весь трафик на backend2 — практика `max_fails`/`fail_timeout` в деле.
4. Прогнать быстрый цикл запросов (`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 на практике.
5. Проверить `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](../../legend/CAPACITY.md).
## Как это ложится в легенду
В реальной работе (АО ТНИИС) — конфиги Nginx для маршрутизации и балансировки перед сервисами, в том числе перед компонентами мониторинга. Домашний кейс воспроизводит тот же принцип на двух простых бэкендах вместо реального внутреннего сервиса.