Этап 3 — CDN, Anycast и edge routing

Сайт находится в дата-центре Франкфурта, а ты в Лондоне. Тебе нужны 30 мс задержки, а до Франкфурта 25 мс по прямой плюс маршрутизация. Решение — Content Delivery Network: тысячи серверов по всему миру, и DNS отправит тебя к ближайшему. Но как именно?

Рабочая ситуация

«Жалоба: пользователи из Австралии видят страницу за 6 секунд, из Европы — за 0,8. Бэкенд один и тот же, метрики сервера идеальные». Прежде чем читать: что бы ты предложил, если переносить сервер в Австралию нельзя? Сколько раз пакету придётся слетать Сидней↔Франкфурт для одного HTTPS-запроса без всяких ускорений? Посчитай — и держи ответ в голове: весь этот урок про то, как эти перелёты убрать.

Что узнаешь — после урока ты сможешь
Вспомни из прошлых уроков

В этапе 2 рекурсивный резолвер вернул браузеру A-запись — и мы отметили две зацепки, которые выстрелят сейчас: ECS (резолвер может сообщить авторитетному серверу подсеть клиента — на этом стоит GeoDNS) и TTL 60 у CDN-записей (частый ре-резолвинг позволяет менять ответы на лету). А из этапа 1 пригодится цена соединения: DNS + TCP + TLS — именно её CDN сокращает, придвигая сервер к тебе.

1. Проблема, которую решает CDN

Без CDN твой сайт — это один (ну или несколько) серверов в одном регионе. Все пользователи мира подключаются к этим серверам напрямую. Это плохо по трём причинам:

⏱️ Latency

Пакет из Сиднея во Франкфурт идёт ~280 мс в одну сторону. Для TLS handshake это ~840 мс. На 200 мс открытия страницы и мечтать нельзя.

📦 Bandwidth

Каждый юзер качает картинки/CSS/JS с твоего сервера. Гигабайты трафика — это деньги и пропускная способность канала origin.

💥 DDoS

10000 ботов одновременно ломятся к одному серверу — он ложится. Невозможно защититься «в одиночку».

🌐 Reliability

Один дата-центр упал — всех клиентов мира нет.

CDN — это распределённая сеть кэш-серверов (edge nodes / points of presence / PoP) в десятках/сотнях городов по всему миру. Каждый юзер подключается к ближайшему. Все они кэшируют твой контент. До твоего origin доходит только малая часть запросов.

2. Как CDN направляет тебя к ближайшему edge

Есть две техники, которые обычно работают вместе:

🗺️ GeoDNS

Authoritative-сервер CDN смотрит, откуда пришёл DNS-запрос (по IP резолвера или ECS), и возвращает разные A-записи разным регионам.

📡 Anycast

Все edge-серверы в мире анонсируют один и тот же IP. Маршрутизаторы интернета (BGP) сами направляют пакет к ближайшему.

3. Anycast — как один IP может быть в 300 городах

Это самая «магическая» часть CDN. Сложно поверить, но 1.1.1.1 Cloudflare существует в ~300 городах одновременно. Каждый сервер слышит на этом IP и отвечает.

Магии нет — есть BGP.

BGP в одном абзаце

BGP — это «протокол маршрутизации между провайдерами». Каждый провайдер интернета (autonomous system, AS) рассказывает своим соседям: «у меня есть путь до сетей X, Y, Z». Соседи рассказывают своим соседям. Так строится глобальная карта.

Cloudflare имеет AS 13335. Они анонсируют 1.1.1.0/24 через BGP в каждой своей точке присутствия. Соседи провайдеров слышат «есть путь до 1.1.1.0/24 через AS 13335 в Лондоне» — и от лондонских узлов начинается «гора» маршрутов вверх по интернету.

Anycast IP 1.1.1.1 — везде SF NY LDN FRA MOW SGP SYD GRU 1.1.1.1 1.1.1.1 1.1.1.1 1.1.1.1 👤 👤 👤 Каждый клиент попадает на ближайший edge — автоматически, через BGP

Когда твой провайдер видит несколько маршрутов до 1.1.1.0/24, он выбирает самый короткий (по количеству AS-хопов и метрикам). А самый короткий — обычно к ближайшему edge.

Что хорошо в anycast

Что плохо

4. GeoDNS — альтернативный способ

Не у всех есть инфраструктура для anycast. Альтернатива — GeoDNS: authoritative-сервер возвращает разные A-записи в зависимости от того, откуда пришёл DNS-запрос.

# Запрос из Лондона
$ dig @ns-cdn.example.com www.example.com
www.example.com.  60  IN  A  93.184.216.34   # лондонский edge

# Тот же запрос из Сиднея
$ dig @ns-cdn.example.com www.example.com
www.example.com.  60  IN  A  104.20.51.10   # сиднейский edge

Authoritative смотрит на IP резолвера (по умолчанию) или на ECS (если резолвер прислал client subnet), сверяется со своей географической базой (MaxMind или своя), отвечает.

Минусы GeoDNS:

На практике большие CDN (Cloudflare, Fastly) используют anycast. Многие облачные (AWS CloudFront) — GeoDNS + anycast комбинированно.

5. PoP — точка присутствия

PoP (Point of Presence) — это «локация» CDN: несколько серверов в одной географической точке, обычно в интернет-обменнике (IX) или коммерческом дата-центре. У крупных CDN сотни PoP по миру.

В PoP стоит:

Когда твой запрос пришёл в PoP, дальнейшая судьба зависит от двух вещей: есть ли ответ в кэше, и какой тип контента ты запрашиваешь.

6. Edge cache — главная экономия

Статические ресурсы (CSS, JS, картинки) кэшируются на edge — иногда на дни/месяцы. Когда ты делаешь запрос:

  1. Edge смотрит свой локальный кэш. Если есть и не истёк → отдаёт cache HIT. Не идёт к origin.
  2. Если истёк или нет → cache MISS. Edge делает запрос к origin (часто — к другому edge посередине, который называется shield). Получает ответ, кэширует, отдаёт клиенту.
  3. Если кэширование запрещено (Cache-Control: no-store) → всегда идёт к origin.

Что управляет кэшированием:

Cache key

Ключ кэша обычно состоит из: host + path + Vary-заголовки + query-string. Дизайн ключа критичен:

# Плохо — каждый запрос с разным campaign_id кэшируется отдельно
example.com/landing?campaign=fb-2024-may&user=12345

# Хорошо — игнорируем tracking-параметры
# Cloudflare Page Rules: «ignore query string»
# или: «cache key — только хост и путь»

7. Инвалидация — как «выкинуть» из кэша

Ты задеплоил новую версию JS. Все клиенты должны получить новый код. Как?

📛 Cache busting

Имя файла содержит хэш или версию: app.a3f9b7.js. Новая версия = новое имя = новый кэш. Лучший способ.

🧹 Purge

API CDN: «удали из кэша вот этот URL». Принудительно. Cloudflare/Fastly умеют — несколько секунд глобально.

⏱️ Низкий TTL

Просто кэшируешь на 60 секунд. Подходит для HTML, но даёт лишнюю нагрузку на origin.

🏷️ Cache tags

Каждый ответ помечается тегами (Cache-Tag: product-42). При обновлении продукта — purge по тегу. Cloudflare Enterprise / Fastly.

8. Origin Shield и cache hierarchy

У CDN не один уровень кэшей — обычно два:

клиент → edge (city)  →  shield (region)  →  origin

           ↑                  ↑                   ↑
        миллион              сотня             один

Origin Shield — это «промежуточный кэш» перед origin. Если у тебя 200 edge'ов в Cloudflare, без shield все 200 могут одновременно делать MISS и идти к origin. С shield — один shield-pop делает запрос, остальные 199 получают копию от shield. Это снижает нагрузку на origin в десятки раз.

Аналогия

CDN — сеть продуктовых магазинов у дома

Origin — это единственный завод: без CDN каждый покупатель мира едет за хлебом прямо на завод. Edge-кэши — магазины у дома: хлеб (статика) лежит на полке, очередь на завод исчезает. Shield — региональный склад: когда у сотни магазинов кончается товар, на завод едет один грузовик со склада, а не сто. Purge — «снять партию с полок во всех магазинах разом», а cache busting — не отзывать старый товар, а выпускать новый под другим артикулом: старый сам долежит до конца срока годности (TTL) и исчезнет.

9. Edge compute — код на edge

Раньше CDN был «тупым» кэшем. Сейчас на edge можно выполнять код:

ПлатформаRuntimeЛимиты
Cloudflare WorkersV8 isolates (JS, WASM, Rust)50 мс CPU, ~128 МБ памяти
AWS Lambda@EdgeNode, Python в CloudFrontнесколько КБ inflated
AWS CloudFront FunctionsJS только, ультра-быстро<1 мс CPU
Fastly Compute@EdgeWASM (любой компилируемый язык)~50 мс
Vercel Edge FunctionsV8 isolates~50 мс

Использования:

10. SSL/TLS на edge

Edge — это точка, где TLS обычно терминируется. То есть зашифрованный канал от клиента заканчивается на edge, а от edge до origin может идти:

Сертификат на edge выпускается обычно автоматически — CDN использует Let's Encrypt или свой CA.

11. Главные CDN и их особенности

Cloudflare

Anycast по всему миру (300+ PoP). Бесплатный план мощный. Сильные edge compute (Workers). DDoS защита. Hard-to-beat для веба и API.

AWS CloudFront

Глубоко интегрирован с AWS (S3, ALB, ACM). Lambda@Edge для логики. Дешёвый, если ты уже в AWS. PoP меньше, чем у Cloudflare.

Fastly

Любим разработчиками — гибкий VCL для тонкой настройки. Используют GitHub, Stripe, NYT. Compute@Edge на WASM.

Akamai

Корпоративный лидер. Огромное количество PoP. Сложный, дорогой, но обслуживает банки и стримеры.

Bunny.net

Молодой, дешёвый, простой. Хорош для статики, видео-стриминга. Любят инди-разработчики.

CDN77, KeyCDN

Среднеценовые альтернативы. Хороши для специфических задач.

12. Мини-лаба: попробуй прямо сейчас

Всё проверяется из обычного терминала — CDN вокруг тебя повсюду:

# Видишь IP, на который попадаешь
dig +short app.cloudflare.com
# Скорее всего покажет несколько A — это разные edge серверов anycast IP

# Какой PoP тебя обслуживает (Cloudflare)
curl -v https://www.cloudflare.com/cdn-cgi/trace
# colo=FRA — Frankfurt edge
# ip=...

# Через CDN ты идёшь или к origin напрямую?
curl -I https://example.com 2>&1 | grep -E '(server|cf-|x-cache|via)'
# server: cloudflare → CDN!
# cf-cache-status: HIT → отдано из кэша edge

# Сравни latency до разных regions
ping cloudflare.com               # anycast — ответит ближайший
ping us-east-1.amazonaws.com      # фиксированный регион

# Что в кэше — твоё или нет (Cloudflare)
curl -I https://www.cloudflare.com/
# cf-cache-status: HIT/MISS/EXPIRED/REVALIDATED/...
Ожидаемый результат

В cdn-cgi/trace строка colo= покажет трёхбуквенный код аэропорта ближайшего к тебе PoP (например, DME/LED/FRA) — это anycast привёл тебя туда без всякого GeoDNS. Запусти curl -I на один и тот же URL дважды: первый ответ может быть cf-cache-status: MISS, повторный — HIT: ты своими глазами наполнил edge-кэш. ping cloudflare.com покажет единицы-десятки миллисекунд — сравни с пингом до конкретного региона облака на другом континенте.

13. Что с этим делает DevOps

14. Задачи самопроверки — реши, потом раскрой ответ

Задача 1. После деплоя новой версии сайта пользователи видят свежий HTML, но старые стили. Статика раздаётся через CDN c Cache-Control: max-age=604800, имена файлов фиксированные (app.css). Что произошло и какие есть два выхода — быстрый и правильный?

Edge-кэши по всему миру имеют право неделю отдавать старый app.css, и origin они даже не спросят. Быстрый выход — purge через API CDN (глобально за секунды). Правильный — cache busting: собирать статику с хэшем в имени (app.a3f9b7.css) и ссылаться на неё из HTML; тогда деплой атомарно переключает клиентов, а purge вообще не нужен.

Задача 2. Сервис на anycast-IP отлично держит HTTP-API, но пользователи WebSocket-чата жалуются на внезапные обрывы раз в несколько часов. Почему и что делать?

BGP-маршруты меняются (перестройка пирингов, отказ узла), и трафик клиента прилетает на другой edge, который ничего не знает про его TCP-сессию — соединение рвётся. Короткие HTTP-запросы этого не замечают, долгоживущие — да. Решения: выносить stateful-трафик на unicast-адреса конкретных узлов, использовать переподключение с восстановлением состояния, или CDN-механизмы для WebSocket, которые держат состояние в распределённом слое.

Задача 3. Пользователь из Сингапура с резолвером 8.8.8.8 попадает на американский edge вашего GeoDNS-CDN, хотя сингапурский PoP есть. В чём причина и что могло бы помочь?

GeoDNS видит IP резолвера, а не клиента. Если запрос Google-резолвера ушёл с американского узла и без ECS — авторитетный сервер честно решил, что клиент в США. Помогает ECS (резолвер сообщает подсеть клиента), выбор резолвера ближе к себе — или anycast, где вопрос снят вовсе: маршрут выбирает сеть, а не DNS.

Задача 4. После включения CDN origin всё равно периодически «захлёбывается» ровно в момент истечения кэша популярной страницы: сотни MISS-запросов одновременно. Как называется этот эффект и чем лечится?

Это cache stampede / thundering herd: TTL истёк везде почти одновременно, и все edge-узлы бросились к origin. Лечение: Origin Shield (к origin ходит один узел, остальные берут у него), request coalescing (CDN склеивает одинаковые MISS в один запрос), stale-while-revalidate (отдавать слегка протухший ответ, пока фоновый запрос обновляет кэш).

Задача 5. Безопасники требуют, чтобы трафик от CDN до origin был зашифрован И чтобы origin принимал соединения только от вашего CDN. Какой режим TLS выбрать и что добавить?

Full (Strict) — HTTPS до origin с проверкой его сертификата — закрывает первое требование. Второе закрывается mTLS (origin требует клиентский сертификат CDN — у Cloudflare это Authenticated Origin Pulls) плюс фильтрация по опубликованным IP-диапазонам CDN. Иначе атакующий, узнав IP origin, обойдёт CDN вместе с его WAF.

15. Словарик урока

точка присутствия · PoP (point of presence)площадка CDN в конкретном городе: кэш, TLS, WAF, edge compute
граничный сервер · edgeближайший к пользователю сервер CDN, отвечающий из кэша
исходный сервер · originтвой настоящий бэкенд, который CDN прикрывает собой
anycastодин IP-префикс анонсируется по BGP из многих точек; сеть сама ведёт к ближайшей
GeoDNSавторитетный сервер отдаёт разные A-записи в зависимости от географии запроса
ключ кэша · cache keyпо чему ищется ответ в кэше: host + path + Vary + query
попадание/промах · cache HIT / MISSответ найден в кэше edge / пришлось идти к origin
щит origin · origin shieldрегиональный кэш-посредник: сотни edge не бомбят origin одновременно
очистка · purgeпринудительное удаление объекта из всех кэшей CDN через API
смена имени · cache bustingновая версия файла = новое имя с хэшем; старый кэш умирает сам
вычисления на границе · edge computeвыполнение кода (JS/WASM) прямо на PoP: A/B, авторизация, geo-логика
терминация TLS · TLS terminationшифрованный канал клиента заканчивается на edge; дальше — свой канал до origin

Чек-лист «понимаю это»

CDN решает latency / bandwidth / DDoS / reliability через сеть кэш-серверов на edge. Доставка к ближайшему — через anycast (BGP) или GeoDNS. Главный смысл — кэш. Инвалидация через cache busting, purge API, низкий TTL, cache tags. Современный edge ещё и компьютит — JS на edge становится нормой.