构建和配置您的 CDN

内容交付网络 (CDN) 在网站和应用程序中使用,主要是为了加快静态元素的加载速度。 发生这种情况是由于位于不同地理区域的 CDN 服务器上缓存了文件。 通过 CDN 请求数据,用户从最近的服务器接收数据。

所有内容分发网络的操作原理和功能大致相同。 CDN服务器收到下载文件的请求后,会从原始服务器一次性获取文件并提供给用户,同时缓存指定的时间段。 所有后续请求都从缓存中得到答复。 所有 CDN 都具有预加载文件、清除缓存、设置到期日期等选项。

碰巧,出于某种原因,您需要组织自己的内容交付网络,然后 - 让组装下一辆自行车的说明对我们有所帮助。

构建和配置您的 CDN
来源: 由 pikisuperstar 创建的信息图表矢量 - www.freepik.com

当您需要自己的 CDN 时

考虑运行您自己的 CDN 有意义的情况:

  • 当想要省钱和运行成本时,即使使用廉价的 CDN(例如 兔子CDN 每月达数百美元
  • 如果我们想要获得永久缓存或没有服务器和通道邻居的缓存
  • CDN 服务在您需要的区域没有存在点
  • 需要任何特殊的内容交付设置
  • 我们希望通过将生产服务器放置在更靠近用户的位置来加速动态内容的交付
  • 人们担心第三方 CDN 服务可能会非法收集或使用有关用户行为的信息(您好,不符合 GDPR 的服务)或从事其他非法活动

在大多数其他情况下,使用现有的现成解决方案更为合适。

你需要开始什么

如果您拥有自己的自治系统 (AS),那就太好了。 有了它,您可以将相同的IP分配给多个服务器并 根据这个指令 在网络层面,将用户引导至最近的网络。 值得一提的是,即使使用/24地址块,也可以构建内容分发网络。 某些服务器提供商允许您发布公告,以便在他们可用的所有区域中使用。

如果您不乐意拥有 IP 地址块,那么要运行简单的 CDN,您将需要:

  • 域名或子域
  • 不同地区至少有两台服务器。 服务器可以是专用服务器,也可以是虚拟服务器
  • 地理域名解析工具。 有了它,用户在寻址域后,将被定向到最近的服务器

注册域名并订购服务器

通过域名注册,一切都很简单 - 我们在任何区域向任何注册商注册。 您还可以使用 CDN 的子域,例如 cdn.域名.com。 实际上,在我们的示例中,我们将这样做。

至于订购服务器,应在您的用户受众所在的地区和国家租用。 如果项目是洲际的,那么选择同时提供世界各地服务器的托管提供商会很方便。 例子: OVH, LEASEWEB и 100Tb - 对于专用服务器, Vultr и DigitalOcean — 用于虚拟云*。

对于我们的私有 CDN,我们将在不同的大陆订购 3 台虚拟服务器。 在 Vultr 在服务器上 $5/月 我们将得到 25GB的SSD 地点和 1TB 流量。 安装时选择最新的Debian。 我们的服务器:

构建和配置您的 CDN 法兰克福,IP:199.247.18.199

构建和配置您的 CDN 芝加哥,IP:149.28.121.123

构建和配置您的 CDN 新加坡,IP:157.230.240.216

*Vultr 和 DigitalOcean 承诺在添加付款方式后立即向通过文章中的链接注册的用户提供 100 美元的赠金。 作者也因此得到了一个小小的称赞,这对于现在的他来说意义重大。 请理解。

设置 geoDNS

为了让用户在访问某个域或CDN子域时能够被定向到所需的(最近的)服务器,我们需要一个具有geoDNS功能的DNS服务器。

geoDNS的原理和操作如下:

  1. 指定发送 DNS 请求的客户端的 IP,或者处理客户端请求时使用的递归 DNS 服务器的 IP。 此类递归服务器通常是提供商的 DNS。
  2. 客户的IP识别他的国家或地区。 为此,使用了目前数量众多的 GeoIP 数据库。 有好的 自由选择.
  3. 根据客户端的位置,为他提供最近的 CDN 服务器的 IP 地址。

具有geoDNS功能的DNS服务器可以 自己组装,但最好使用现成的解决方案以及遍布世界各地的 DNS 服务器网络 任播 从盒子里:

  • 云DNS$9.95/月,GeoDNS资费,默认有XNUMX个DNS Failover
  • 齐洛尔$25/月, DNS 故障转移已启用
  • 亚马逊路线53$35/月 净 50M 地理请求。 DNS 故障转移单独计费
  • 简化DNS$125/月,有 10 个 DNS 故障转移
  • Cloudflare, 企业计划中提供“地理转向”功能

订购 geoDNS 时,您应该注意资费中包含的请求数量,并记住,对该域的实际请求数量可能会超出预期数倍。 数以百万计的蜘蛛、扫描仪、垃圾邮件发送者和其他邪灵不知疲倦地工作。

几乎所有的DNS服务都包含构建CDN不可或缺的一项服务——DNS Failover。 借助它,您可以设置对服务器运行的监控,并在没有生命迹象的情况下,自动将 DNS 响应中的备用服务器地址替换为不工作的服务器地址。

为了构建我们的 CDN,我们将使用 域名解析、GeoDNS 资费。

让我们在您的个人帐户中添加一个新的 DNS 区域,指定您的域。 如果我们在子域上构建 CDN,并且主域已在使用中,那么在添加区域后,不要忘记立即添加现有的工作 DNS 记录。 下一步是为 CDN 域/子域创建多个 A 记录,每个 A 记录都将应用于我们指定的区域。 您可以指定大洲或国家/地区作为区域,子区域适用于美国和加拿大。

在我们的例子中,CDN 将在子域上提出 cdn.sayt.in。 通过添加区域 萨伊特,为子域创建第一个 A 记录,并将整个北美指向芝加哥的服务器:

构建和配置您的 CDN
让我们对其他区域重复这一操作,记住为默认区域创建一个条目。 最终会发生以下情况:

构建和配置您的 CDN

屏幕截图中的最后一个默认条目意味着所有未指定的区域(欧洲、非洲、卫星互联网用户等)都将发送到法兰克福的服务器。

这样就完成了基本的 DNS 设置。 仍需前往域名注册商网站,将当前域名 NS 替换为 ClouDNS 颁发的域名 NS。 在更新 NS 的同时,我们将准备服务器。

SSL 证书的安装

我们的 CDN 将通过 HTTPS 运行,因此如果您已经拥有某个域或子域的 SSL 证书,请将它们上传到所有服务器,例如上传到目录 /etc/ssl/yourdomain/

如果没有证书,您可以从 Let's Encrypt 获取免费的证书。 非常适合这个 ACME Shell脚本。 该客户端方便且易于设置,最重要的是,它允许您通过 ClouDNS API 通过 DNS 验证域/子域。

我们将仅在其中一台服务器上安装 acme.sh - 欧洲 199.247.18.199,证书将从该服务器复制到所有其他服务器。 要安装,请运行:

root@cdn:~# wget -O - https://get.acme.sh | bash; source ~/.bashrc

在安装脚本的过程中,将创建一个 CRON 作业,用于在没有我们参与的情况下进一步更新证书。

颁发证书时,将使用 API 使用 DNS 来检查域名,因此在 Reseller API 菜单中的 ClouDNS 个人帐户中,您需要创建一个新的用户 API 并为其设置密码。 生成的 auth-id 和密码将写入文件中 〜/.acme.sh/dnsapi/dns_cloudns.sh (不要与文件混淆 dns_云d域名服务器)。 以下是需要取消注释和编辑的行:

CLOUDNS_AUTH_ID=<auth-id>
CLOUDNS_AUTH_PASSWORD="<пароль>"

现在我们将请求 SSL 证书 cdn.sayt.in

root@cdn:~# acme.sh --issue --dns dns_cloudns -d cdn.sayt.in --reloadcmd "service nginx reload"

在选项中,为了将来,我们指定了一个命令,用于在以后每次更新证书有效期后自动重新加载Web服务器配置。

整个获取证书的过程最多需要2分钟,请勿中断。 如果发生域验证错误,请尝试再次运行该命令。 最后我们将看到证书已上传到哪里:

构建和配置您的 CDN

请记住这些路径,将证书复制到其他服务器以及 Web 服务器设置时需要指定它们。 我们不注意重新加载 Nginx 配置的错误 - 更新证书时它不会出现在完全配置的服务器上。

我们剩下的 SSL 工作就是将收到的证书复制到另外两台服务器,同时维护文件的路径。 让我们在每个目录上创建相同的目录并制作一个副本:

root@cdn:~# mkdir -p /root/.acme.sh/cdn.sayt.in/
root@cdn:~# scp -r root@199.247.18.199:/root/.acme.sh/cdn.sayt.in/* /root/.acme.sh/cdn.sayt.in/

要定期更新证书,请使用以下命令在两台服务器上创建每日 CRON 作业:

scp -r root@199.247.18.199:/root/.acme.sh/cdn.sayt.in/* /root/.acme.sh/cdn.sayt.in/ && service nginx reload

在这种情况下,必须配置对远程源服务器的访问 通过按键, IE。 无需输入密码。 别忘了去做。

安装和配置 Nginx

为了提供静态内容,我们将使用配置为缓存代理服务器的 Nginx。 更新软件包列表并将其安装在所有三台服务器上:

root@cdn:~# apt update
root@cdn:~# apt install nginx

我们使用下面剧透中的配置来代替默认配置:
nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log off;
    error_log /var/log/nginx/error.log;

    gzip on;
    gzip_disable "msie6";
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_vary on;
    gzip_types text/plain application/javascript text/javascript text/css application/json application/xml text/xml application/rss+xml;
    gunzip on;            

    proxy_temp_path    /var/cache/tmp;
    proxy_cache_path   /var/cache/cdn levels=1:2 keys_zone=cdn:64m max_size=20g inactive=7d;
    proxy_cache_bypass $http_x_update;

server {
  listen 443 ssl;
  server_name cdn.sayt.in;

  ssl_certificate /root/.acme.sh/cdn.sayt.in/cdn.sayt.in.cer;
  ssl_certificate_key /root/.acme.sh/cdn.sayt.in/cdn.sayt.in.key;

  location / {
    proxy_cache cdn;
    proxy_cache_key $uri$is_args$args;
    proxy_cache_valid 90d;
    proxy_pass https://sayt.in;
    }
  }
}

在配置中编辑:

  • 最大尺寸 — 缓存的大小,不超过可用磁盘空间
  • 不活跃 - 无人访问的缓存数据的存储时间
  • ssl_certificate и ssl_certificate_key — SSL 证书和密钥文件的路径
  • 代理缓存有效 - 缓存数据的存储时间
  • 代理通行证 — CDN 将请求文件进行缓存的原始服务器的地址。 在我们的例子中,这 萨伊特

如您所见,一切都很简单。 由于指令的相似性,仅在设置缓存时间时才会出现困难 不活跃 и 代理缓存有效。 让我们用我们的例子来分析它们。 以下是当发生以下情况时 不活动=7天 и proxy_cache_valid 90d:

  • 如果7天内没有重复请求,则该数据将从缓存中删除
  • 如果请求至少每 7 天重复一次,那么缓存中的数据将在 90 天后被视为过时,Nginx 将使用下一个请求更新它,从原始服务器获取它

编辑完成 nginx.conf,重新加载配置:

root@cdn:~# service nginx reload

我们的 CDN 已准备就绪。 每月 15 美元。 我们在三大洲都有接入点和 3 TB 流量:每个位置 1 TB。

检查CDN的工作情况

让我们看看不同地理位置对 CDN 的 ping 操作。 任何 ping 服务都适用于此。

发射点
主持人
IP
平均时间,毫秒

德国 柏林
cdn.sayt.in
199.247.18.199
9.6

荷兰,阿姆斯特丹
cdn.sayt.in
199.247.18.199
10.1

法国 巴黎
cdn.sayt.in
199.247.18.199
16.3

英国、伦敦
cdn.sayt.in
199.247.18.199
14.9

加拿大,多伦多
cdn.sayt.in
149.28.121.123
16.2

美国, 旧金山
cdn.sayt.in
149.28.121.123
52.7

美国, 达拉斯
cdn.sayt.in
149.28.121.123
23.1

美国, 芝加哥
cdn.sayt.in
149.28.121.123
2.6

美国, 纽约
cdn.sayt.in
149.28.121.123
19.8

新加坡
cdn.sayt.in
157.230.240.216
1.7

日本 东京
cdn.sayt.in
157.230.240.216
74.8

澳大利亚, ​​悉尼
cdn.sayt.in
157.230.240.216
95.9

结果很好。 现在我们将在主站点的根目录中放置一个测试图像 test.jpg 并通过 CDN 检查其下载速度。 据说 - DONE。 内容交付很快。

让我们编写一个小脚本,以防我们想要清除 CDN 点上的缓存。
清除程序

#!/bin/bash
if [ -z "$1" ]
then
    echo "Purging all cache"
    rm -rf /var/cache/cdn/*
else
    echo "Purging $1"
    FILE=`echo -n "$1" | md5sum | awk '{print $1}'`
    FULLPATH=/var/cache/cdn/${FILE:31:1}/${FILE:29:2}/${FILE}
    rm -f "${FULLPATH}"
fi

要删除整个缓存,只需运行它,就可以像这样清理一个单独的文件:

root@cdn:~# ./purge.sh /test.jpg

而不是结论

最后,我想给出一些有用的提示,以便立即跨过当时让我头疼的耙子:

  • 为了提高CDN的容错能力,建议配置DNS Failover,这有助于在服务器故障时快速更改A记录。 这是在域的控制面板 DNS 记录中完成的。
  • 地理覆盖范围广的网站无疑需要大量的CDN,但我们不要狂热。 如果您将服务器放置在 6-7 个位置:欧洲、北美(东部)、北美(西部)、新加坡、澳大利亚、香港或日本,那么与付费 CDN 相比,用户很可能不会注意到显着差异
  • 有时,托管服务商不允许将租用的服务器用于 CDN 目的。 因此,如果您突然决定将内容交付网络部署为服务,请不要忘记提前阅读特定托管提供商的规则
  • 探索 水下通讯地图表示各大洲如何连接,并在构建内容交付网络时考虑到这一点
  • 尝试检查 来自不同地方的 ping 到您的服务器。 这样您就可以看到最接近 CDN 点的区域并更正确地配置 GeoDNS
  • 根据任务的不同,根据特定的缓存要求并考虑服务器上的负载来微调 Nginx 会很有用。 关于 Nginx 缓存的文章对我帮助很大 - 这里 和重载下工作的加速: 这里 и 这里

来源: habr.com