Балансировка нагрузки и failover
Балансировка нагрузки и failover
1) Цели и термины
Балансировка распределяет трафик между экземплярами/зонами/регионами для производительности и устойчивости.
Failover — управляемое переключение при отказе.
RTO/RPO: целевое время восстановления и допустимая потеря данных.
SLO: целевой уровень доступности/латентности; служит «воротами» для автоматического фейловера и отката.
2) Слои балансировки
2.1 L4 (TCP/UDP)
Плюсы: производительность, простота, TLS passthrough. Минусы: нет понимания маршрута/куки.
Примеры: NLB/GLB, HAProxy/Envoy L4, IPVS.
2.2 L7 (HTTP/gRPC)
Плюсы: маршрутизация по пути/хедерам, канареечные веса, sticky. Минусы: дороже по CPU/латентности.
Примеры: NGINX/HAProxy/Envoy/Cloud ALB/API Gateway.
2.3 Глобальный уровень
DNS/GSLB: health-checks + гео/взвешенный ответ.
Anycast/BGP: один IP по миру, ближайшая точка анонса.
CDN/Edge: кеш/фейловер на периметре.
3) Алгоритмы распределения
Round-robin / weighted — базовые.
Least connections / latency — для «тяжелых» запросов.
Consistent hashing — клейкость по ключу (user/tenant) без центровой сессии.
Hash-based locality — для кэшей и stateful-сервисов.
4) Сессии и клейкость (sticky)
Cookie-sticky: L7 LB устанавливает cookie для возврата к экземпляру.
Src-IP sticky: на L4, хуже при NAT/CGNAT.
Consistent hashing: лучше для горизонтальных кэшей/чатов.
Aim: по возможности делайте сервис stateless, иначе — выносите состояние (сессии в Redis/DB), чтобы упрощать failover.
5) Надежность: health-checks и выведение из ротации
Active checks: HTTP 200/глубокие пробы бизнес-пути (например, `/healthz/withdraw` с зависимостями).
Passive (outlier detection): эжекция бэкендов при 5xx/таймаутах.
Warm-up: плавное включение новых инстансов (slow-start).
Graceful drain: удалить из пула → дождаться завершения запросов.
nginx upstream api {
zone api 64k;
least_conn;
server app-1:8080 max_fails=2 fail_timeout=10s;
server app-2:8080 max_fails=2 fail_timeout=10s;
keepalive 512;
}
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 2;
Envoy outlier detection (фрагмент):
yaml outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50
6) Управление сбоями: timeout/retry/circuit-breaking
Timeouts: короче, чем таймаут клиента; задавать per-route.
Retries: 1–2 с джиттером и идемпотентностью; запрет ретраев на POST без ключей идемпотентности.
Circuit breaker: ограничение одновременных запросов/ошибок; «полуоткрытое» восстановление.
Budgets: лимиты ретраев/слияние бурстов, чтобы не устроить self-DDOS.
7) Kubernetes-паттерны
ClusterIP/NodePort/LoadBalancer/Ingress — базовые примитивы.
Readiness/Liveness: трафик только на готовые поды.
PodDisruptionBudget: недопустить одновременное падение N реплик.
HPA/VPA: масштабирование по CPU/RED метрикам, связка с LB.
ServiceTopology/Topology Aware Hints: локальность по зоне.
Service type=LoadBalancer (zonal): минимум — по 2 реплики в каждой AZ.
yaml readinessProbe:
httpGet: { path: /healthz/dependencies, port: 8080 }
periodSeconds: 5 failureThreshold: 2
8) Кросс-зонный и кросс-региональный трафик
Multi-AZ (внутри региона): распределяйте равномерно (zonal LB), хранение — синхронные реплики.
Multi-region:- Active-Active: оба региона обслуживают трафик; сложнее — нужна репликация данных, согласованность и маршрутизация по географии.
- Active-Passive: основной регион обслуживает, резерв — «горячий/теплый/холодный». Проще, быстрее переключение, но выше RPO.
- Geo-DNS (ближайший регион).
- Weighted DNS (канарейки/перераспределение).
- Latency-based (RTT-измерения).
- Failover = по сигналам здоровья/доступности (probes с нескольких vantage-точек).
9) Данные и failover
Кэш/стейт: по возможности — регионально локальный; для Active-Active — CRDT/консистентные хэши.
БД:- Синхронная репликация = низкий RPO, выше латентность.
- Асинхронная = ниже латентность, но RPO>0.
- Очереди: зеркалирование/мультикластерные топики; дедупликация событий.
- Проектируйте идемпотентность операций и replay-механику.
10) Периметр: DNS/Anycast/BGP/CDN
DNS: короткий TTL (30–60s) + health-checks вне вашей сети.
Anycast: несколько POP’ов с одним IP — ближайший принимает трафик, фейловер на уровне маршрутизации.
CDN/Edge: кэш и «шлюз» для защиты, статика/медиa обслуживаются при падении origin; origin-shield + пер-POP health.
11) Образцы конфигураций
HAProxy L7:haproxy defaults timeout connect 2s timeout client 15s timeout server 15s retries 2 option redispatch
backend api balance leastconn option httpchk GET /healthz/dependencies http-check expect status 200 server app1 app-1:8080 check inter 5s fall 2 rise 2 slowstart 3000 server app2 app-2:8080 check inter 5s fall 2 rise 2 slowstart 3000
NGINX sticky по cookie:
nginx upstream api {
hash $cookie_session_id consistent;
server app-1:8080;
server app-2:8080;
}
Envoy retry/timeout (route):
yaml route:
timeout: 2s retry_policy:
retry_on: 5xx,connect-failure,reset num_retries: 1 per_try_timeout: 500ms
12) Автоматический failover: сигналы и гейты
Тех-SLI: 5xx-rate, p95/p99, saturation, хэндшейки TLS, TCP resets.
Бизнес-SLI: успех депозитов/выплат, нет платежных ошибок у PSP.
Гейты: при превышении порогов — отключить зону/инстанс, поднять веса стабильного пула, переключить GSLB.
Runbook: пошаговая инструкция переключения и возврата (rollback).
13) Тесты и инспекции (chaos & game-days)
Chaos-тесты: отключение AZ/регионов, деградации БД/кэшей, симуляция packet-loss.
Game-day: тренировочный фейловер с участием on-call команд.
Диагностика: трассировка от периметра до бэкендов, сопоставление релиз-аннотаций и метрик.
14) Безопасность и комплаенс
mTLS между LB↔сервисы, WAF/Rate limits на периметре.
Зоны отказа/сегментации: изоляция blast-radius.
Политики: запрет одиночных точек отказа (SPOF), требования по «минимум N реплик/AZ».
15) Анти-паттерны
Один LB/одна зона для всего прод-трафика (SPOF).
Отсутствие глубокой проверки `/healthz` (зеленое — но БД/очередь недоступны).
Ретрай без идемпотентности → дубль операций/платежей.
Sticky per IP при массовом NAT → дисбаланс.
DNS-фейловер с высокими TTL (часы до переключения).
Нет graceful drain при деплое — обрыв запросов.
16) Чек-лист внедрения (0–45 дней)
0–10 дней
Разнести инстансы по ≥2 AZ; включить readiness/liveness, health-checks.
Настроить L7-timeouts/retries (1 попытка), outlier detection.
Включить graceful drain и slow-start.
11–25 дней
Ввести GSLB (geo/weighted) или Anycast для периметра.
Канареечные веса/политики маршрутов; sticky через cookie/consistent hash.
SLO-гейты для авто-фейловера (p95/5xx + бизнес-SLI).
26–45 дней
Региональный DR: Active-Active или Active-Passive с тестом перевода.
Chaos-дни с отключением AZ/регионов, отчеты RTO/RPO.
Автоматизированные runbook’и (скрипты pause/shift/rollback).
17) Метрики зрелости
Покрытие Multi-AZ ≥ 99% критичных путей.
DNS/GSLB/Anycast внедрены для публичных эндпоинтов.
MTTR при падении одной AZ < 5 минут (p95).
RPO для критичных данных ≤ целевого (например, ≤ 30 секунд).
Ежеквартальные game-days и успешный плановый фейловер.
18) Заключение
Надежная балансировка и failover — это слоеная архитектура: локальные L7-политики (timeouts/retries/CB, health-checks), правильная клейкость и хэширование, кросс-зонная устойчивость, а на периметре — GSLB/DNS/Anycast. Добавьте SLO-гейты, идемпотентность, graceful drain и регулярные chaos-тесты — и любая потеря узла, зоны или даже региона станет управляемым событием с предсказуемым RTO/RPO.