Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке CDN і навіщо воно потрібне?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**CDN (Content Delivery Network)** - це розподілена мережа проксі-серверів, яка кешує статичні ресурси (JS, CSS, зображення) і роздає їх з точок, найближчих до користувача. ```html <!-- Найближчий edge-сервер: ~50ms замість ~400ms від віддаленого origin --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> ``` **Ключове:** CDN скорочує затримку на 50-80% і знімає 70-95% статичного трафіку з основного сервера.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**CDN (Content Delivery Network)** - це глобальна мережа проксі-серверів, яка кешує статичні ресурси і роздає їх з точок, найближчих до користувача. ## Теорія ### TL;DR - CDN - як мережа піцерій: місцева точка видає піцу з готового тіста (кеш), а не чекає поставки від центрального складу з іншого кінця країни - Скорочує затримку з 200-500ms до 20-100ms, направляючи запити до найближчого Point of Presence (PoP) - Знімає 70-95% статичного трафіку з основного сервера - Варто додавати при глобальній аудиторії або коли статичні файли (зображення, JS, CSS) складають більшу частину трафіку ### Швидкий приклад ```html <!-- Без CDN: кожен запит іде на твій єдиний сервер --> <link rel="stylesheet" href="/styles.css"> <!-- Користувач у США при сервері в ЄС: ~400ms затримки --> <!-- З CDN: найближчий edge-сервер роздає закешовану копію --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> <!-- Затримка: ~50ms, файл закешований глобально --> ``` Відкрий вкладку Network в DevTools. Запит через CDN покаже малий TTFB (Time to First Byte). Запит до origin - великий. Це і є та різниця, яку CDN усуває. ### Головна різниця Без CDN кожен запит до ресурсу потрапляє на твій єдиний origin-сервер, незалежно від того, де знаходиться користувач. Людина в Токіо, яка завантажує файл із сервера у Франкфурті, чекає 300-500ms до появи першого байта. CDN перехоплює цей запит на токійському edge-сервері й роздає закешовану копію за 20-50ms. Origin підключається лише при першому запиті до файлу або після закінчення TTL. ### Коли використовувати CDN - Глобальна аудиторія з користувачами в різних країнах: CDN скорочує географічну затримку на 50-80% - Сайт із важкими статичними ресурсами (зображення, JS-бандли, шрифти складають більшість трафіку): CDN - Пікові навантаження навколо запусків продукту або розпродажів: CDN поглинає трафік без падіння сервера - Локальний прототип або внутрішній інструмент для кількох людей: достатньо звичайного хостингу - Суто динамічний API без кешованих відповідей: CDN тут не допоможе ### Як CDN працює зсередини Браузер резолвить CDN-хостнейм через anycast DNS до найближчого PoP. Edge-сервер перевіряє кеш (за TTL, наприклад `Cache-Control: max-age=3600` для JS-файлів). Є в кеші - роздає одразу з диска або пам'яті. Немає - запитує origin, зберігає копію, потім роздає. Ця pull-модель стоїть за замовчуванням у CloudFront і Cloudflare. Такі провайдери, як Akamai, запускають Varnish-подібні проксі з LRU-витісненням на цих вузлах. Ключовий момент: заголовки `Cache-Control` у відповіді твого origin-сервера визначають, як довго CDN тримає файл. ### Типові помилки **Немає заголовків Cache-Control.** Якщо origin не надсилає заголовки кешування, CDN вважає кожен файл некешованим і пересилає всі запити на origin. Нуль користі. ```js // Неправильно: без заголовків CDN не може нічого кешувати app.use('/static', express.static('public')); // Правильно: кажемо CDN тримати файли рік app.use('/static', express.static('public', { maxAge: '1y', immutable: true })); ``` **Забули про інвалідацію кешу після деплою.** Ти задеплоїв новий `app.js`, але назва файлу та сама. CDN роздає стару версію до закінчення TTL, іноді кілька днів. Рішення: хеш у назві файлу (`app.abc123.js`). Vite і Webpack роблять це автоматично. **Кешування динамічного або персоналізованого контенту.** `Cache-Control: public, max-age=3600` на маршруті `/api/user/profile` означає, що CDN закешує дані одного користувача і роздасть їх усім іншим. Для персональних даних - тільки `Cache-Control: private, no-cache`. ### Де використовується на практиці - React/Vite: production-збірка виводить `dist/assets/index-[hash].js`, завантажується на CDN з immutable-заголовками кешу - Next.js: Edge Network від Vercel автоматично кешує все з `_next/static` - Express: Cloudflare перед папкою `public/`, плюс заголовки кешу на статичних відповідях - Netflix: власна CDN під назвою Open Connect доставляє 99% відеотрафіку через обладнання, вбудоване прямо в мережі провайдерів ### Follow-up питання **Q:** Як DNS-резолвінг працює в CDN? **A:** CDN-провайдери використовують anycast-маршрутизацію. Одна IP-адреса оголошується з сотень локацій по всьому світу, і DNS веде до найближчої. `cdn.cloudflare.com` може резолвитись у Франкфурті для берлінського користувача і в Далласі для користувача з Х'юстона. **Q:** Яка різниця між push і pull CDN? **A:** Pull CDN (за замовчуванням у CloudFront і Cloudflare) сам забирає контент з origin при першому промаху кешу і зберігає копію. Push CDN вимагає попередньо завантажити контент до того, як прийдуть запити. Push підходить для великих файлів, як-от відеоманіфести, коли ти вже знаєш, що попит буде. **Q:** Як керувати інвалідацією кешу в масштабі? **A:** Стандартний підхід - інвалідація за шляхом (`/images/*`) через API CDN. Повне скидання кешу - крайній захід, бо спричиняє хвилю запитів до origin. Краще проєктувати систему так, щоб інвалідація була не потрібна: хеш у назвах файлів означає, що URL змінюється з кожним деплоєм, а старі записи в CDN стають недосяжними самі по собі. **Q:** Коли CDN погіршує продуктивність? **A:** Перший запит після промаху кешу (cold start) додає затримку, бо edge мусить звернутись до origin. Надмірне кешування динамічного контенту призводить до застарілих даних. Петлі редиректів трапляються, коли CDN і origin по черзі намагаються перенаправити один і той самий URL один до одного. ## Приклади ### Підключення Bootstrap через CDN Найпростіший кейс: завантаження бібліотеки з публічного CDN замість самостійного хостингу. ```html <!DOCTYPE html> <html> <head> <!-- Роздається з найближчого jsDelivr PoP, закешовано глобально --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" /> </head> <body> <button class="btn btn-primary">Натисни</button> </body> </html> ``` Файл вже закешований на edge-серверах jsDelivr по всьому світу. Користувач у Токіо отримує його з токійського PoP. Користувач у Бразилії - з місцевого. Твій сервер у цьому не бере участі взагалі. ### Інвалідація кешу в Express і CloudFront Тут більшість джунів стикаються з реальним багом. Ти оновлюєш файл на S3, але користувачі годинами бачать стару версію. ```js const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); const { CloudFrontClient, CreateInvalidationCommand } = require('@aws-sdk/client-cloudfront'); const s3 = new S3Client({ region: 'us-east-1' }); const cf = new CloudFrontClient({ region: 'us-east-1' }); app.post('/update-image', async (req, res) => { // Завантажуємо новий файл на S3 await s3.send(new PutObjectCommand({ Bucket: 'myapp-assets', Key: 'img.jpg', Body: req.body })); // Інвалідуємо кеш CDN, щоб користувачі отримали нову версію await cf.send(new CreateInvalidationCommand({ DistributionId: 'E123ABC', InvalidationBatch: { Paths: { Quantity: 1, Items: ['/img.jpg'] }, CallerReference: Date.now().toString() } })); res.json({ ok: true }); }); ``` Без виклику інвалідації користувачі бачать старий `img.jpg` до 24 годин (дефолтний TTL CloudFront). З ним кеш очищається за менш ніж 5 хвилин. Цей баг я бачив у продакшені мінімум тричі в командах, що вперше будували щось на S3 і CloudFront.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.