О насБлогКонтакты
Архитектура ПО8 сентября 2016 г. 4 мин 111Обновлено: 22 июня 2026 г.

Как настроить CDN для казахстанского сайта и ускорить загрузку в регионах (2016)

AunimedaAunimeda
📋 Содержание

Коротко: Подключите Cloudflare (бесплатный план) - смените NS-серверы домена, включите кэширование статики. Cloudflare имел PoP в Москве и Франкфурте - пользователи из регионов Казахстана получали контент с ~80ms вместо ~200ms. Для видео и больших файлов - Amazon CloudFront с S3.


Без CDN: задержки из регионов КЗ (2016)

Сервер в Алматы → пользователь в разных городах:

Алматы    →  15ms  (внутри города)
Астана    →  45ms
Шымкент   →  55ms
Актобе    →  120ms
Атырау    →  150ms
Усть-Каменогорск → 130ms

С Cloudflare PoP Москва (ближайший к КЗ):
Алматы    →  40ms  (через Москву - хуже)
Астана    →  60ms
Все города → 50-90ms (лучше для регионов)

В 2016 году у Cloudflare не было PoP в Казахстане - ближайший был в Москве и Франкфурте. Для статичного контента это всё равно давало выигрыш за счёт кэширования у пользователя.


Шаг 1: Подключение Cloudflare

1. Зарегистрироваться на cloudflare.com
2. Add a Site → ввести mysite.kz
3. Cloudflare сканирует текущие DNS-записи
4. Изменить NS-серверы у регистратора:
   - Было:   ns1.hoster.kz, ns2.hoster.kz
   - Стало:  alice.ns.cloudflare.com, bob.ns.cloudflare.com
5. Дождаться распространения DNS (1-48 часов)

Cloudflare: правила кэширования

Cloudflare Dashboard → Caching → Page Rules:

Правило 1: Кэшировать статику
URL: *.mysite.kz/static/*
Action: Cache Level = Cache Everything
Edge Cache TTL: 1 month

Правило 2: НЕ кэшировать API
URL: *.mysite.kz/api/*
Action: Cache Level = Bypass

Правило 3: НЕ кэшировать корзину и личный кабинет
URL: *.mysite.kz/cart*
Action: Cache Level = Bypass
URL: *.mysite.kz/account*
Action: Cache Level = Bypass

nginx: заголовки для CDN

# Статические файлы - разрешить кэширование в CDN
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, max-age=2592000, immutable";
    # immutable = браузер не проверяет обновление до истечения TTL
}

# HTML страницы - условное кэширование
location / {
    add_header Cache-Control "public, max-age=300, s-maxage=600";
    # max-age=300 - браузер кэширует 5 минут
    # s-maxage=600 - CDN (Cloudflare) кэширует 10 минут
    # s-maxage переопределяет max-age только для CDN
}

# API - запретить кэширование
location /api/ {
    add_header Cache-Control "no-store, no-cache, private";
}

# Версионированные ассеты (hash в имени файла)
# app.a1b2c3d4.css - можно кэшировать вечно
location ~* \.[a-f0-9]{8}\.(css|js)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Версионирование ассетов (Cache Busting)

<?php
// PHP: добавлять hash к URL статических файлов

class Assets {
    private static array $manifest = [];

    public static function url(string $path): string {
        // Загрузить манифест версий (генерируется при сборке)
        if (empty(self::$manifest)) {
            $manifestPath = public_path('build/manifest.json');
            if (file_exists($manifestPath)) {
                self::$manifest = json_decode(file_get_contents($manifestPath), true);
            }
        }

        if (isset(self::$manifest[$path])) {
            return '/build/' . self::$manifest[$path];
        }

        // Fallback: добавить timestamp
        return $path . '?v=' . filemtime(public_path($path));
    }
}
// build/manifest.json - генерируется Webpack при сборке
{
    "css/app.css":    "css/app.a1b2c3d4.css",
    "js/app.js":      "js/app.e5f6g7h8.js",
    "js/vendor.js":   "js/vendor.i9j0k1l2.js"
}
<!-- В шаблоне -->
<link rel="stylesheet" href="<?= Assets::url('css/app.css') ?>">
<!-- Вывод: /build/css/app.a1b2c3d4.css - кэшируется вечно -->

Amazon CloudFront для медиафайлов

<?php
// MediaUploader.php - загрузка изображений в S3 + CloudFront

use Aws\S3\S3Client;

class MediaUploader {
    private S3Client $s3;
    private string   $bucket;
    private string   $cdnUrl;  // CloudFront distribution URL

    public function upload(string $localPath, string $s3Key): string {
        // Загрузить в S3
        $this->s3->putObject([
            'Bucket'       => $this->bucket,
            'Key'          => $s3Key,
            'SourceFile'   => $localPath,
            'ContentType'  => mime_content_type($localPath),
            'CacheControl' => 'public, max-age=31536000',
            'ACL'          => 'public-read',
        ]);

        // Вернуть CloudFront URL (не S3 URL - CDN кэширует)
        return $this->cdnUrl . '/' . $s3Key;
        // https://d1234abcd.cloudfront.net/products/image.jpg
    }

    public function getThumbUrl(string $s3Key, int $width, int $height): string {
        // Параметры трансформации через CloudFront Lambda@Edge (2017+)
        // В 2016: хранить несколько размеров заранее
        $thumbKey = str_replace('.jpg', "_{$width}x{$height}.jpg", $s3Key);
        return $this->cdnUrl . '/' . $thumbKey;
    }
}

Инвалидация CDN кэша при обновлении

<?php
// При обновлении товара - инвалидировать CDN кэш страницы

class CacheInvalidator {
    public function invalidateProductPage(int $productId): void {
        // Cloudflare API: очистить кэш конкретного URL
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => 'https://api.cloudflare.com/client/v4/zones/' . CF_ZONE_ID . '/purge_cache',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'X-Auth-Email: ' . CF_EMAIL,
                'X-Auth-Key: ' . CF_API_KEY,
                'Content-Type: application/json',
            ],
            CURLOPT_POSTFIELDS => json_encode([
                'files' => [
                    'https://mysite.kz/products/' . $productId,
                    'https://mysite.kz/products/' . $productId . '/',
                    'https://mysite.kz/catalog/',  // Список товаров тоже обновить
                ]
            ]),
        ]);
        curl_exec($curl);
        curl_close($curl);
    }
}

Результаты после CDN (2016, KZ)

Интернет-магазин, сервер в Алматы, Cloudflare + S3/CloudFront:

Метрика Без CDN С CDN
Загрузка страницы (Алматы) 1.8с 1.2с
Загрузка страницы (Астана) 3.1с 1.6с
Загрузка страницы (Актобе) 4.8с 2.1с
Трафик на origin сервер 100% 18% (82% из CDN кэша)
Стоимость сервера базовая -30% (меньше нагрузки)

CDN уменьшил трафик на сервер на 82%. Это сказалось на стоимости хостинга - можно было использовать сервер меньшей мощности.

Читайте также

Мобильное приложение для бизнеса в Казахстане: Flutter, стоимость и когда оно нужноaunimeda
Мобильная разработка

Мобильное приложение для бизнеса в Казахстане: Flutter, стоимость и когда оно нужно

Когда бизнесу в Казахстане нужно мобильное приложение, а когда достаточно сайта? Flutter vs React Native для казахстанского рынка, стоимость разработки и ключевые интеграции.

Разработка сайта в Алматы 2026: цены, технологии и как выбрать студиюaunimeda
Веб-разработка

Разработка сайта в Алматы 2026: цены, технологии и как выбрать студию

Сколько стоит разработка сайта в Алматы в 2026 году? Сравниваем технологии, типы сайтов и даём практическое руководство по выбору IT-партнёра для бизнеса в Казахстане.

Telegram бот для бизнеса в Алматы и Казахстане: зачем, как, сколькоaunimeda
CRM и автоматизация

Telegram бот для бизнеса в Алматы и Казахстане: зачем, как, сколько

Как Telegram бот помогает бизнесу в Казахстане автоматизировать приём заявок, поддержку клиентов и уведомления. Стоимость разработки в Алматы и реальные кейсы применения.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Казахстане. Бесплатная консультация.

Получить консультацию Все статьи