Initial commit: interview prep repo (resume, legend, stack cases, Kubernetes course)
This commit is contained in:
111
stack/nginx/CASE.md
Normal file
111
stack/nginx/CASE.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Кейс: 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 для маршрутизации и балансировки перед сервисами, в том числе перед компонентами мониторинга. Домашний кейс воспроизводит тот же принцип на двух простых бэкендах вместо реального внутреннего сервиса.
|
||||
Reference in New Issue
Block a user