Files
resume/stack/nginx/CASE.md

5.5 KiB
Raw Blame History

Кейс: 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. Шаги воспроизведения

  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.

Как это ложится в легенду

В реальной работе (АО ТНИИС) — конфиги Nginx для маршрутизации и балансировки перед сервисами, в том числе перед компонентами мониторинга. Домашний кейс воспроизводит тот же принцип на двух простых бэкендах вместо реального внутреннего сервиса.