DNS, балансировка, reverse proxy

↑ 1.1 Сети и протоколы для бэкенда · ← Предыдущая · → Следующая

Желательно~5 мин чтенияУровень: junior

Зачем это на собесе

В микросервисной архитектуре запрос проходит DNS, балансировщик и reverse proxy (в проекте — nginx-gateway перед GraphQL-шлюзом и public API). Нужно понимать, как запрос находит сервис и где могут теряться заголовки, IP и таймауты.

Подтемы

  • DNS для бэкенда: записи, TTL, внутренний DNS, кэш в .NET
  • Балансировка L4 и L7, алгоритмы, health checks
  • Reverse proxy: задачи и конфигурация nginx
  • YARP и ForwardedHeaders в ASP.NET Core

Объяснение

DNS для бэкенда

  • Записи: A/AAAA (IP), CNAME (псевдоним), SRV (хост и порт сервиса, используется в service discovery), TXT.
  • TTL определяет, как долго клиенты кэшируют ответ. При переключении трафика TTL уменьшают заранее.
  • Внутренний DNS: Docker Compose даёт встроенный DNS, и сервисы доступны по имени (http://patient_storage:8080). В Kubernetes — service.namespace.svc.cluster.local.
  • .NET кэширует DNS внутри SocketsHttpHandler на время жизни соединения → PooledConnectionLifetime, чтобы подхватывать смену IP.
services.AddHttpClient<PatientClient>()
    .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
    {
        PooledConnectionLifetime = TimeSpan.FromMinutes(2),  // пересоздавать соединения → свежий DNS
    });

Балансировка нагрузки

  • L4 (транспортный): распределяет TCP- и UDP-соединения, не видит HTTP. Быстро (IPVS, AWS NLB).
  • L7 (прикладной): видит HTTP: маршрутизация по пути и заголовкам, TLS-терминация, sticky-сессии, ретраи (nginx, HAProxy, Envoy, YARP).

Алгоритмы: round robin, weighted, least connections, IP hash (консистентное хеширование для липкости).

Проверки здоровья: балансировщик исключает инстансы, не прошедшие health check, — отсюда важность /health/ready.

Reverse proxy

Сервер-посредник перед приложениями. Задачи:

  • единая точка входа, маршрутизация /api/* → сервисы, / → статика фронта;
  • TLS-терминация, сжатие, кэш, ограничение размера тела, rate limiting;
  • скрытие внутренней топологии.
upstream gateway { server fusion_gateway:8080; keepalive 32; }
server {
  listen 443 ssl;
  location /graphql {
    proxy_pass http://gateway;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 60s;
  }
}

YARP — reverse proxy на .NET

Библиотека Microsoft для построения прокси и API gateway прямо в ASP.NET Core (маршруты, кластеры, трансформации, балансировка).

// ASP.NET Core за прокси: восстановить реальные IP и схему
builder.Services.Configure<ForwardedHeadersOptions>(o =>
{
    o.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    o.KnownNetworks.Clear(); o.KnownProxies.Clear();   // или явно указать IP прокси
});
app.UseForwardedHeaders();   // самым первым middleware

Нюансы и подводные камни

  • Sticky sessions — костыль для stateful-сервиса. Лучше stateless-сервисы и состояние в БД или Redis.
  • Таймауты по цепочке должны уменьшаться к центру: клиент > nginx > gateway > сервис > БД. Иначе внешний уровень рвёт соединение, а работа внутри продолжается.
  • Балансировщик L7 и долгие соединения (WebSocket, gRPC-стримы): нужны Upgrade-заголовки и увеличенные таймауты.
  • HTTP/2 к бэкенду из nginx для gRPC — grpc_pass, а не proxy_pass.
  • Кэш DNS в долгоживущих клиентах — причина «сервис переехал, а трафик идёт на старый IP».

Вопросы с ответами

Связанные темы