Перейти к содержанию

B02 · Приём трафика: LB, proxy, gateway, CDN#

Всё, что стоит между пользователем и вашим кодом. Этот слой решает три задачи: довести запрос до живого экземпляра, снять с приложения то, что дешевле сделать на границе, и не пустить внутрь лишнее.

Блок описывает компоненты — балансировщик, прокси, API gateway, CDN. И свойства — rate limiting (ограничение частоты), защиту от перегрузки и злоупотреблений, service discovery (обнаружение сервисов), глобальную маршрутизацию.

Навигация: EDGE-01 · EDGE-02 · EDGE-03 · EDGE-04 · EDGE-05 · EDGE-06 · EDGE-07 · EDGE-08 · EDGE-09


EDGE-01 · Балансировка нагрузки: L4 против L7#

Шаг W5

TL;DR. Балансировщик распределяет запросы между экземплярами и убирает отказавшие из ротации. Уровень, на котором он работает, определяет, что он умеет и сколько стоит.

Проблема. Один экземпляр — это и потолок ёмкости, и единая точка отказа. Когда экземпляров несколько, нужно решать, кто получит следующий запрос. При этом экземпляры неодинаковы: часть прогревается, часть отвечает медленнее, часть уже мертва, но об этом ещё никто не знает (DIST-06).

Как работает.

  • L4 работает с соединениями: решает по адресу и порту, содержимое не разбирает. Быстро, дёшево, подходит для любого протокола поверх TCP/UDP. Не маршрутизирует по пути или заголовку и не завершает TLS.
  • L7 разбирает запрос: маршрутизация по пути, заголовкам, cookie; завершение TLS; переписывание заголовков; повторы и таймауты на уровне запроса. Дороже по ресурсам, зато на нём строятся выкатка по долям трафика, версионирование API и маршруты BFF (backend for frontend).

Алгоритмы распределения.

Алгоритм Когда уместен Слабое место
По кругу (round-robin) Однородные экземпляры, однородные запросы Игнорирует разницу в стоимости запросов
Взвешенный Экземпляры разной мощности Веса надо поддерживать
Наименьшее число соединений Запросы разной длительности Требует состояния на балансировщике
Наименьшая задержка Разнородные бэкенды Может «сгрудить» трафик на быстром узле
По хэшу ключа Нужна локальность кэша (DATA-11) Перекос при неравномерных ключах
Случайный из двух (power of two choices) Хорошее приближение «наименее загруженного» без глобального состояния Чуть хуже точного выбора

Что ещё должен уметь балансировщик.

  • health checks (проверки здоровья), активные и пассивные (REL-05);
  • outlier detection (отсев выбросов) — временно исключать экземпляр, который отвечает ошибками или слишком медленно;
  • плавно выводить экземпляр из ротации при выкатке: дожидаться завершения текущих запросов;
  • ограничивать число соединений к бэкенду.

Липкие сессии (sticky sessions) привязывают пользователя к экземпляру. Это возвращает состояние на узлы, мешает равномерности и делает выкатку заметной для пользователя. Применять их стоит, только когда состояние действительно нельзя вынести (DIST-01).

Trade-offs и режимы отказа. Балансировщик и сам — точка отказа: его резервируют и выводят под общий адрес (EDGE-09). Долгоживущие соединения (HTTP/2, gRPC, WebSocket) ломают L4-балансировку. Одно соединение несёт множество вызовов и остаётся на одном бэкенде, поэтому нагрузка распределяется неравномерно (NET-10). Слишком агрессивные health checks выводят живые узлы под нагрузкой и сокращают ёмкость как раз тогда, когда она нужна.

Что мерить.

  • распределение запросов и задержки по бэкендам — перекос первым выдаёт проблему;
  • число экземпляров вне ротации;
  • долю ошибок соединения;
  • время вывода узла из ротации.

Связано: EDGE-02 proxy · EDGE-03 API gateway · REL-05 health checks · EDGE-08 service discovery · NET-02 модель OSI

Источники: Envoy — Load balancing · NGINX — HTTP Load Balancing · Google SRE Book, гл. 19–20 · ByteByteGo — Top 6 Load Balancing Algorithms Every Developer Should Know · ByteByteGo — What is a LOAD BALANCER really about?


EDGE-02 · Proxy и reverse proxy#

Шаг W4

TL;DR. Forward proxy (прямой прокси) действует от имени клиента и скрывает его. Reverse proxy (обратный прокси) стоит перед серверами и представляет их. Разница — в том, чьи интересы прокси обслуживает.

Как работает.

  • Forward proxy клиент настраивает у себя: контроль исходящего трафика, кэш, обход ограничений, сокрытие клиента. В серверных системах он важен как egress gateway (исходящий шлюз) — единственная точка, через которую сервисы ходят наружу, с белым списком адресов. Заодно это защита от подделки запросов на стороне сервера (SEC-07): сервис не может обратиться куда угодно.
  • Reverse proxy стоит перед вашими серверами и для клиента неотличим от них. Он снимает с приложения то, что дешевле сделать один раз на границе:
    • завершение TLS;
    • сжатие;
    • кэширование ответов (NET-06);
    • отдачу статики;
    • буферизацию медленных клиентов;
    • ограничение размера тела;
    • переписывание путей.

Буферизация — недооценённая функция. Reverse proxy принимает запрос у медленного клиента целиком и только потом передаёт бэкенду; с ответом — наоборот. Приложение не держит поток, пока данные идут по медленной сети. Это простой способ поднять эффективную ёмкость и защита от атак с медленной отправкой данных.

Когда что. Reverse proxy стоит перед приложением почти в любой системе. Forward proxy — когда нужно контролировать исходящие обращения сервисов.

Trade-offs и режимы отказа. Ещё один сетевой участок — ещё одни таймауты, и их надо согласовать с таймаутами приложения. Прокси, который обрывает соединение раньше, чем приложение успевает ответить, даёт 504 при работающем бэкенде. Прокси видит расшифрованный трафик, а значит становится объектом требований безопасности. Настройки буферов и лимитов, оставленные по умолчанию, — частая причина загадочных 413 и 502 на больших запросах.

Что мерить.

  • долю ответов, отданных прокси без обращения к приложению;
  • время до первого байта — отдельно от времени приложения;
  • ошибки на участке прокси — бэкенд;
  • число активных соединений.

Связано: EDGE-01 балансировка · EDGE-03 API gateway · EDGE-05 CDN · NET-06 HTTP-кэширование

Источники: NGINX — Reverse proxy · Cloudflare — What is a reverse proxy? · ByteByteGo — Proxy vs Reverse Proxy (Real-world Examples)


EDGE-03 · API gateway#

Шаг W4

TL;DR. API gateway (API-шлюз) — единая точка входа для API. Он берёт на себя сквозные заботы: аутентификацию, лимиты, маршрутизацию, observability (наблюдаемость). От балансировщика и прокси его отличает не механика, а зона ответственности.

Проблема. Когда сервисов больше одного, каждый вынужден сам проверять токены, считать лимиты, логировать, поддерживать CORS и версии. Это дублирование, которое расходится: в одном сервисе проверка строгая, в другом забыли. Клиенту при этом приходится знать адреса всех сервисов.

Разграничение:

Компонент Отвечает за Не отвечает за
Балансировщик Распределение между экземплярами, здоровье Смысл запроса
Reverse proxy Транспортные заботы: TLS, кэш, сжатие, буферизация Идентичность клиента
API gateway Аутентификация, авторизация на входе, лимиты, маршрутизация по API, версии, агрегация, ключи Бизнес-логику

Что уместно вынести в API gateway.

  • проверку подлинности токена — но не бизнес-правила доступа: они остаются в сервисе, который знает предметную область;
  • rate limiting (ограничение частоты; EDGE-06);
  • выдачу и учёт ключей API;
  • маршрутизацию по версии и по доле трафика;
  • присвоение идентификатора запроса и начало трассировки (OPS-07);
  • преобразование протоколов на границе, например HTTP наружу и gRPC внутрь.

Чего не стоит. Бизнес-логики и агрегации, специфичной для одного клиента: последнее — работа BFF (backend for frontend, ARCH-10), отдельного сервиса, а не общего API gateway. Если в API gateway переехала логика, он становится общим узким местом: изменения в нём блокируют все команды сразу.

Trade-offs и режимы отказа. API gateway — общая точка отказа и общая точка выкатки: его конфигурация должна быть простой, проверяемой и откатываемой. Централизованная аутентификация создаёт соблазн доверять внутренним вызовам без проверки. Но любой обход API gateway — внутренний вызов, отладочный порт — снимает всю защиту. Поэтому сервисы должны проверять права сами (SEC-04). Управляемые API gateway облачных провайдеров навязывают лимиты на размер тела и время ответа — их нужно знать заранее.

Что мерить.

  • задержку, добавленную API gateway, — отдельно от бэкенда;
  • долю отказов на входе по причинам: аутентификация, лимит, маршрут;
  • время выкатки конфигурации и число откатов.

Связано: EDGE-04 точка входа · EDGE-06 rate limiting · ARCH-10 BFF · SEC-01 аутентификация

Источники: microservices.io — API Gateway · Kong — What is an API gateway · ByteByteGo — What is API Gateway? · ByteByteGo — Reverse Proxy vs API Gateway vs Load Balancer


EDGE-04 · Точка входа: маршрутизация и выкатка на границе#

Шаг W9

TL;DR. Граница — единственное место, где видно весь трафик до его разветвления. Поэтому здесь дешевле всего делать постепенную выкатку и переключение версий.

Проблема. Новая версия сервиса готова. Выкатить сразу на всех — значит узнать о проблеме от пользователей. Держать две версии и переключать их конфигурацией приложения — значит размазать логику выкатки по всем сервисам. При этом клиенты обращаются по путям, которые не должны меняться при каждом изменении внутренней топологии.

Как работает.

  • Маршрутизация по пути, хосту и заголовку отвязывает публичный адрес от внутреннего устройства: /api/orders может обслуживаться одним сервисом сегодня и тремя завтра.
  • Доли трафика. Правило вида «5 % на новую версию» реализуется на границе и не требует участия сервисов. На этом строится canary (канареечная выкатка; OPS-02).
  • Маршрутизация по признаку: заголовку, cookie, tenant ID (идентификатору арендатора). Применения — внутреннее тестирование на реальном трафике, ранний доступ, отладка конкретного клиента.
  • Зеркалирование трафика (traffic mirroring) — копия запросов уходит на новую версию, ответы отбрасываются. Так новая версия получает живую нагрузку и живые данные без риска для пользователя.
  • В Kubernetes эту роль играет ingress или gateway кластера; в облаке — балансировщик прикладного уровня с правилами; в service mesh (сервисной сетке) — правила маршрутизации (ARCH-10).

Когда применять. Как только выкатка должна быть постепенной, а публичные адреса — стабильными. Когда нет: для одного сервиса без версий правила на границе только добавляют слой.

Trade-offs и режимы отказа. Правила маршрутизации — конфигурация, которая ведёт себя как код, но обычно не проходит тех же проверок. Ошибка в правиле отправляет трафик в никуда — мгновенно и для всех. Зеркалирование удваивает нагрузку на зависимости и опасно для операций с побочными эффектами — зеркалить безопасно только чтение. Долгоживущие соединения не переключаются на новую версию сами: доли трафика работают для запросов, а не для установленных сессий (NET-12).

Что мерить.

  • долю трафика по версиям — фактическую, а не заданную;
  • ошибки и задержку в сравнении между версиями;
  • время применения изменённых правил;
  • число откатов.

Связано: EDGE-03 API gateway · OPS-02 стратегии выкатки · REL-04 фича-флаги · EDGE-09 глобальная маршрутизация

Источники: Kubernetes — Ingress · Kubernetes — Gateway API · Istio — Traffic management


EDGE-05 · CDN и edge-кэширование#

Шаг W5

TL;DR. CDN — сеть точек присутствия, которая отдаёт контент из ближайшей к пользователю. Она сокращает и расстояние, и нагрузку на ваши серверы; обычно это самая дешёвая оптимизация из существующих.

Проблема. Пользователь в другом полушарии платит сотни миллисекунд только за дорогу (NET-01), а ваши серверы тратят ёмкость на раздачу одинаковых файлов. Пик трафика от популярного контента приходит на инфраструктуру, рассчитанную на обычную нагрузку.

Как работает.

  • Точки присутствия (points of presence, PoP) расставлены по всему миру; запрос попадает в ближайшую по сетевым метрикам (EDGE-09).
  • Кэширование по правилам ответа (NET-06): ключ кэша — URL плюс заголовки из Vary. Управление ключом — например, игнорирование маркетинговых параметров запроса — заметно повышает hit ratio (долю попаданий).
  • Request coalescing (объединение запросов). При промахе несколько одновременных запросов к источнику схлопываются в один — встроенная защита от cache stampede (лавины запросов к источнику; CACHE-04).
  • Ярусное кэширование (tiered caching): между точкой присутствия и источником стоит промежуточный ярус, снижающий число обращений к источнику ещё на порядок.
  • Динамика тоже ускоряется, даже если её нельзя кэшировать: соединение до ближайшей точки устанавливается быстро, а дальше запрос идёт по оптимизированной сети с уже установленными соединениями.
  • Вычисления на границе (edge computing) — простая логика (перенаправления, A/B-разбиение, подпись, персонализация заголовков) выполняется в точке присутствия, не доходя до источника.
  • Инвалидация — сброс по ключу или тегу; надёжнее не сбрасывать, а менять адрес (NET-06).

Когда применять. Статика — без исключений. Публичные ответы API — в большинстве случаев. Медиа и загрузки — обязательно (DATA-12). Когда нет: персонализированные ответы кэшировать нельзя, но их всё равно имеет смысл проводить через сеть провайдера ради ускорения транспорта.

Trade-offs и режимы отказа. Кэш на границе — самый далёкий от вас: инвалидация занимает от секунд до минут и не даёт строгих гарантий. Поэтому персональные данные не должны попадать в разделяемый кэш ни при каких условиях: ошибка в Vary — это утечка. Отладка усложняется: ответ может прийти из десятков разных точек с разным состоянием. Стоимость исходящего трафика — основная статья расходов, и она зависит от региона.

Что мерить.

  • hit ratio по типам контента;
  • долю трафика, дошедшего до источника;
  • задержку по регионам;
  • стоимость исходящего трафика;
  • время распространения инвалидации.

Связано: NET-06 HTTP-кэширование · CACHE-01 уровни кэша · EDGE-09 глобальная маршрутизация · DATA-12 object storage

Источники: Cloudflare — What is a CDN? · MDN — HTTP caching · Fastly — Cache control tutorial · ByteByteGo — What Is A CDN? How Does It Work?


EDGE-06 · Rate limiting#

Шаг W8

TL;DR. Rate limiting (ограничение частоты) — контракт: сколько запросов клиент может сделать за интервал. Он защищает от злоупотреблений и от случайного цикла в чужом коде, но не заменяет реакцию на перегрузку.

Проблема. Один клиент с ошибкой в цикле повторов способен занять всю ёмкость сервиса. Публичный API без лимитов — приглашение выгрузить все данные. При этом ограничение должно быть предсказуемым: клиент должен понимать, сколько ему можно и что делать при отказе.

Усиливающий потребитель бывает своим же сервисом, а не только внешним интегратором. В отчёте GitHub о доступности за август 2026 три инцидента из пяти гасились ограничением входящей нагрузки. В двух из них усиление шло изнутри: runners (исполнители CI), повторявшие уже отозванные задания, и ошибка повторов у клиента, бившая по внутренней точке аутентификации. Лимит только по внешнему периметру этого класса не ловит. Частоту отсюда брать нельзя. Пять инцидентов одного провайдера за месяц — не выборка, а разборы публикует тот, кто умеет расследовать. Отсюда берутся механизм и словарь, а не «чаще».

Алгоритмы

Алгоритм Как считает Свойства
Fixed window (фиксированное окно) Счётчик на минуту Просто; всплеск на границе окон вдвое выше лимита
Sliding log (скользящий журнал) Метки времени всех запросов Точно; дорого по памяти
Sliding window counter (скользящее окно со счётчиками) Взвешенная сумма текущего и прошлого окна Хорошее приближение при малых затратах — практический выбор
Leaky bucket (дырявое ведро) Очередь с постоянной скоростью вытекания Сглаживает, добавляет задержку
Token bucket (токенное ведро) Токены копятся с постоянной скоростью, запрос тратит токен Допускает всплеск в пределах накопленного — ближе всего к реальному поведению клиентов

Что важно на практике.

  • Ключ важнее величины, а автоматизм важнее ключа. Лимит считают по ключу API, пользователю, адресу, tenant (арендатору), эндпоинту — обычно по нескольким сразу: дорогой эндпоинт получает свой лимит помимо общего. Но ограничитель, который включает дежурный посреди инцидента, — средство восстановления, а не защита. В том же отчёте GitHub прямой причиной того, что нагрузку пришлось душить вручную, названо отсутствие автоматической защиты. Порог, по которому ограничитель срабатывает сам, — часть решения, а не улучшение к нему.
  • Контракт в заголовках: оставшаяся квота, момент сброса и, при отказе, Retry-After вместе с кодом 429 (NET-05). Без этого клиент повторяет вслепую и усугубляет ситуацию.
  • Распределённый счётчик. При нескольких экземплярах лимит общий: обычно хранилище в памяти со счётчиками (CACHE-05) и атомарным инкрементом. Компромисс: строгий общий счётчик — лишний сетевой вызов на каждый запрос; локальные счётчики с периодической синхронизацией — дешевле, но лимит соблюдается приблизительно.
  • Плавная реакция. Помимо отказа возможны замедление ответа и понижение приоритета — для внутренних клиентов это часто уместнее.

Когда применять. Любой публичный API; дорогие операции; защита от перебора на аутентификации (SEC-06). Когда нет: ограничение не спасает от перегрузки, вызванной легитимным трафиком в пределах лимитов — для этого нужен load shedding (сброс нагрузки; REL-03).

Trade-offs и режимы отказа. Слишком строгий лимит ломает нормальных клиентов при всплеске — token bucket с запасом обычно ближе к реальности, чем жёсткое окно. Лимит по адресу бьёт по всем, кто за общим NAT. Хранилище счётчиков становится зависимостью на горячем пути: при его недоступности нужно решить заранее — пропускать всё или отклонять всё, и обычно правильный ответ первый. У авторизации ответ обратный (SEC-04): там падать надо в запрет. Направление отказа — свойство операции и её инварианта, а не системы.

Что мерить.

  • долю 429 в разрезе клиентов и эндпоинтов;
  • распределение потребления квоты: кто упирается в потолок;
  • число клиентов, повторяющих без учёта Retry-After;
  • задержку проверки лимита.

Связано: REL-03 load shedding · EDGE-07 защита периметра · CACHE-05 Redis · CASE-04 кейс: rate limiter

Источники: GitHub — отчёт о доступности за август 2026 · Cloudflare — What is rate limiting? · Stripe — Rate limiters · RFC 6585 — 429 Too Many Requests · Google SRE Book, гл. 21


EDGE-07 · Защита периметра: WAF, DDoS, боты#

Шаг W8

TL;DR. Часть угроз дешевле отсекать до того, как запрос дойдёт до приложения. Периметр не заменяет безопасность приложения, а снимает с него объём.

Проблема. Приложение не должно тратить ресурсы на заведомо вредный трафик: перебор паролей, сканирование уязвимостей, парсинг каталога, объёмная атака на отказ. Обрабатывать это в бизнес-логике поздно и дорого: к моменту проверки уже потрачены соединение, поток и запрос к БД.

Слои защиты.

  • Объёмные атаки (переполнение канала, наводнение пакетами) отражаются только на уровне сети провайдера — у вас физически нет столько канала. Это аргумент за размещение за сетью с распределённой ёмкостью (EDGE-05).
  • Атаки на уровне приложения — много правдоподобных запросов на дорогой эндпоинт. Их отражают rate limiting (EDGE-06), load shedding (сброс нагрузки; REL-03) и удорожание запроса для клиента — задача-подтверждение (proof of work).
  • WAF (web application firewall, межсетевой экран уровня приложений) — фильтр по сигнатурам и правилам: инъекции, обход путей, известные уязвимости библиотек. Ценность в двух вещах: отсечение массового сканирования и виртуальное исправление (virtual patching). Это правило, которое закрывает свежую уязвимость за часы, пока выкатывается настоящее исправление. Безопасного кода WAF не заменяет (SEC-07): в частных случаях его обходят, а на нестандартных данных он даёт ложные срабатывания.
  • Управление ботами. Не все боты вредны: поисковые нужны, парсеры конкурентов и перебор учётных данных — нет. Различают их по репутации адреса, отпечатку клиента и поведению. Проверка человечности (CAPTCHA) — крайняя мера: она ухудшает опыт и обходится сервисами разгадывания.
  • Аутентификация как периметр. Самая эффективная защита дорогих эндпоинтов — сделать их доступными только после входа: анонимный дорогой поиск — приглашение к злоупотреблению.

Когда применять. Публичный сервис в интернете. Когда нет: внутренние сервисы за пределами публичного доступа защищают идентичностью и сетевой политикой (SEC-09), а не сигнатурами.

Trade-offs и режимы отказа. WAF даёт ложные срабатывания на легитимных данных — например, на тексте с кавычками и SQL-подобными фрагментами в поле комментария. Поэтому его включают сначала в режиме наблюдения. Правила периметра — общая конфигурация, ошибка в которой блокирует всех пользователей мгновенно. Автоматическая блокировка адресов при работе клиентов за общим NAT отключает целые организации. Проверка человечности на пути оплаты стоит конверсии.

Что мерить.

  • долю заблокированного трафика по причинам;
  • ложные срабатывания — по жалобам и обращениям в поддержку;
  • долю автоматизированного трафика;
  • время от появления уязвимости до правила;
  • расход ёмкости на отражение атак.

Связано: EDGE-06 rate limiting · SEC-07 типовые атаки · SEC-06 безопасность API · REL-03 load shedding

Источники: OWASP — Web Application Firewall · Cloudflare — What is a DDoS attack? · OWASP — Automated Threats to Web Applications


EDGE-08 · Service discovery#

Шаг W4

TL;DR. Service discovery (обнаружение сервисов) отвечает на вопрос «по какому адресу сейчас живёт сервис X». Без него адреса зашиты в конфигурацию, и каждое изменение состава требует выкатки.

Проблема. Экземпляры появляются и исчезают постоянно: автоскейлинг, выкатка, отказ узла, переезд между зонами. Список адресов в конфигурационном файле устаревает в момент записи. Нужен реестр, который знает актуальный состав и, что важнее, не отдаёт адреса мёртвых экземпляров.

Как работает.

  • Регистрация. Экземпляр сам сообщает о себе при старте и подтверждает жизнеспособность — это самостоятельная регистрация (self-registration). Либо это делает платформа, которая наблюдает за процессами, — регистрация третьей стороной (third-party registration). Так устроен Kubernetes: реестром служат объекты сервисов и списки готовых адресов.
  • Обнаружение. На стороне клиента (client-side): клиент получает список и сам выбирает экземпляр (EDGE-01). Это убирает лишний сетевой участок и хорошо работает с gRPC. На стороне сервера (server-side): клиент обращается по стабильному адресу, а выбор делает балансировщик или прокси. Клиенту проще, но добавляется сетевой участок.
  • DNS как транспорт обнаружения — самый распространённый вариант, но с оговоркой: кэширование записей клиентами и библиотеками делает реакцию на изменения медленной и плохо предсказуемой (NET-01).
  • Здоровье — часть реестра. Регистрация без проверки состояния бесполезна: реестр должен убирать экземпляры, которые перестали подтверждать жизнеспособность (DIST-06).
  • Реестр как консенсусное хранилище (etcd, Consul, ZooKeeper) даёт согласованный ответ (DIST-05). Gossip-протоколы (распространение слухов) дают масштаб ценой временных расхождений.

Когда применять. Больше одного сервиса и динамический состав экземпляров. Когда нет: для трёх статичных серверов конфигурация проще и надёжнее реестра.

Trade-offs и режимы отказа. Реестр — критическая зависимость: при его недоступности новые соединения перестают устанавливаться. Отсюда правило — клиенты кэшируют последний известный состав и продолжают работать при отказе реестра (REL-06). Слишком быстрое удаление экземпляра из реестра при кратковременном сбое проверки вызывает колебания состава; слишком медленное — трафик на мёртвые адреса. Кэш DNS у клиента живёт дольше, чем указано в записи, поэтому вывод экземпляра требует ожидания, а не только изменения реестра.

Что мерить.

  • время от старта экземпляра до получения трафика;
  • время от отказа до исключения из реестра;
  • долю запросов на несуществующие адреса;
  • расхождение представлений о составе между клиентами.

Связано: EDGE-01 балансировка · DIST-06 обнаружение отказов · ARCH-10 service mesh · DIST-05 консенсус

Источники: microservices.io — Service registry · HashiCorp Consul — Service discovery · Kubernetes — Service


EDGE-09 · Глобальная маршрутизация: anycast, GSLB, geo-DNS#

Шаг W7

TL;DR. Как пользователь попадает в нужную площадку — и как этот выбор меняется, когда площадка отказывает. Это верхний уровень балансировки, работающий между дата-центрами.

Проблема. Система работает в нескольких регионах (REL-08). Нужно, чтобы пользователь попадал в ближайший, при отказе региона переключался на другой, и чтобы это происходило быстрее, чем истечёт терпение пользователя. Механизм этого переключения — самая недооценённая часть многорегиональной схемы: сама репликация обычно продумана, а маршрутизация остаётся на DNS с суточным TTL (сроком жизни) записи.

Механизмы.

  • Geo-DNS. Ответ DNS зависит от расположения запрашивающего резолвера. Просто, работает везде. Слабость — TTL записи: клиенты и промежуточные резолверы кэшируют дольше объявленного. Поэтому переключение занимает от минут до часов, а часть трафика продолжает идти в отказавший регион. Кроме того, положение резолвера может не совпадать с положением пользователя.
  • Anycast. Один и тот же адрес объявляется из многих точек, и маршрутизация сети сама доставляет пакет в ближайшую. Переключение происходит на уровне маршрутов, без участия клиента, — это лучший из доступных механизмов быстрого переключения. Так работают CDN и публичные DNS-резолверы. Ограничение — состояние соединения: при изменении маршрутов TCP-сессия может разорваться. Для коротких запросов это несущественно, для длинных требует внимания.
  • Глобальный балансировщик (GSLB, global server load balancing) — облачный сервис, выбирающий площадку по здоровью и близости, обычно поверх anycast-адреса. Даёт проверки состояния и явные правила переключения.
  • Выбор на стороне клиента. Приложение получает список площадок и само измеряет доступность. Даёт быструю реакцию и полный контроль, но требует логики в клиенте и его обновления.

Что важно. Переключение должно опираться на health check (проверку здоровья) площадки целиком — сквозной запрос, а не пинг. Ему нужны гистерезис против колебаний и проверка учениями (REL-10): иначе о том, что переключение не работает, вы узнаете в момент аварии.

Trade-offs и режимы отказа. Низкий TTL DNS-записей ускоряет переключение, но увеличивает нагрузку на DNS, а соблюдают его не все клиенты. Автоматическое переключение при ложном срабатывании перебрасывает весь мир в резервный регион, у которого может не хватить ёмкости на полный трафик. Резервный регион либо держат готовым к полной нагрузке, либо принимают деградацию. Разделение пользователей по регионам конфликтует с географией данных: пользователь, чьи данные в одном регионе, а трафик пришёл в другой, получает межрегиональные обращения на каждый запрос.

Что мерить.

  • задержку по регионам;
  • распределение трафика по площадкам;
  • фактическое время переключения в учениях, а не расчётное;
  • долю запросов, обслуженных не «своим» регионом.

Связано: REL-08 multi-region · EDGE-05 CDN · NET-01 DNS · REL-07 ячеистая архитектура

Источники: Cloudflare — What is Anycast? · AWS — Global Accelerator и Route 53 routing policies · Google SRE Book, гл. 19 «Load Balancing at the Frontend»