Сеть доставки контента (Content Delivery Network) или CDN может быть крайне полезна при отдаче статического контента, такого как картинки, css и javascript. CDN позволяет сократить время загрузки страницы в браузере за счет нескольких моментов:
- контент размещен на сервере который располагается наиболее близко к пользователю, что существенно увеличивает скорость загрузки;
- распределение запросов по разным доменам, а все современные браузеры имеют лимит на количество одновременных подключений к одному домену.
Однако очень небольшое число сайтов в интернете использует cdn. Основная тому причина — тарифы на услуги CDN начинаются от нескольких тысяч рублей в месяц. Для тех кто платит за хостинг или VPS 200-500 рублей в месяц дороговато.
Я хочу рассказать о варианте создания своего CDN, причем его стоимость на порядок ниже тарифов таких компаний как CDNvideo, NGENIX или Akamai.
Начнем с первой части задачи, необходимо отдавать контент с сервера который находится наиболее близко к конечному пользователю. Наиболее эффективно, на мой взгляд, сделать это с помощью DNS. Есть несколько вариантов реализации такого сценария:
- GeoDNS BIND patch — патч в 40 строк добавляющий к функционалу views сервера BIND возможность взаимодействие с MaxMind’s GeoIP C API
- elegant Linux BASH script that can be used to help configure BIND to be geo-aware
- powerdns + geo backend
Я остановился на втором варианте, о нем речь далее и пойдет. Для примера настройки буду использовать домен cdn.rascal.su.
Итак, первое что нам понадобится это скрипт GeoIP.sh который мы берем отсюда.
Скрипт выполняет половину работы:
root@ns1:/etc/bind# mkdir geo
root@ns1:/etc/bind# cd geo
root@ns1:/etc/bind/geo# wget http://cdn.rascal.su/uploads/2012/12/GeoIP.sh_.gz
root@ns1:/etc/bind/geo# gunzip GeoIP.sh_.gz
root@ns1:/etc/bind/geo# bash GeoIP.sh_
--2012-12-15 16:58:40-- http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
Resolving geolite.maxmind.com (geolite.maxmind.com)... 174.36.207.186
Connecting to geolite.maxmind.com (geolite.maxmind.com)|174.36.207.186|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1574629 (1.5M) [application/zip]
Saving to: `GeoIPCountryCSV.zip'
100%[=========================================================>] 1,574,629 509K/s in 3.0s
2012-12-15 16:58:44 (509 KB/s) - `GeoIPCountryCSV.zip' saved [1574629/1574629]
Creating CBE (Country,Begin,End) CSV file...DONE
Generating BIND GeoIP.acl file...DONE
На выходе работы скрипта получаем GeoIP.acl, который содержит соответствие ip-адреса и страны в формате BIND ACL. Пришла очередь настройки view в named.conf.
include "/etc/bind/geo/GeoIP.acl";
# CDN for SNG
view "russia" {
match-clients { AM; AZ; BY; GE; KG; KZ; RU; TM; TJ; UA; UZ; };
recursion no;
zone "cdn.rascal.su" {
type master;
file "/etc/bind/master/ru.cdn.rascal.su";
};
};
# CDN for Others
view "global" {
match-clients { any; };
recursion no;
zone "cdn.rascal.su" {
type master;
file "/etc/bind/master/de.cdn.rascal.su";
};
};
Файл зоны ru.cdn.rascal.su:
$ORIGIN .
$TTL 3600 ; 1 hour
cdn.rascal.su IN SOA ns1.rascal.su. hostmaster.rascal.su. (
2 ; serial
900 ; refresh (15 minutes)
600 ; retry (10 minutes)
86400 ; expire (1 day)
3600 ; minimum (1 hour)
)
$TTL 0 ; 0 seconds
NS ns1.rascal.su.
NS ns2.rascal.su.
$TTL 3600 ; 1 hour
A 62.76.187.192
Файл зоны de.cdn.rascal.su:
$ORIGIN .
$TTL 3600 ; 1 hour
cdn.rascal.su IN SOA ns1.rascal.su. hostmaster.rascal.su. (
2 ; serial
900 ; refresh (15 minutes)
600 ; retry (10 minutes)
86400 ; expire (1 day)
3600 ; minimum (1 hour)
)
$TTL 0 ; 0 seconds
NS ns1.rascal.su.
NS ns2.rascal.su.
$TTL 3600 ; 1 hour
A 78.47.49.45
На всех DNS-серверах должен использоватьcя тип master для зон, а их синхронизация должна выполняться внешними средствами.