Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

本站改版后的架构与优化——Hexo,分区解析,CDN,图像压缩等

By: James Guo
14 March 2022 at 11:59

去年,我把我的网站从 WordPress 迁移到了 Hexo。随后的一段时间里,我对 Hexo 进行了大量定制,包括修改主题,实现图片自适应,适配视频等。

基础架构

本站使用 Hexo 博客框架生成静态网页,使用 Nginx 服务器分发静态网页、图片等。本站的静态文件和图片同时部署在全球四台服务器上,使用 Route 53 实现了分区解析和宕机后自动切换,使用 CloudFront 和 UPYUN CDN 分发视频。

主题

本站主题是在 Claudia 的基础上进行定制与魔改。原主题就有如下功能:

  • 移动端适配
  • 评论插件集成
  • 页面边栏 (个人信息,最近文章等)
  • 自适应设备的深色模式
  • 目录自动生成
  • 现代化的设计语言
Claudia 主题封面

我对其增加的功能主要如下:

图片

  • 自动为文章中图片增加 srcset 和 sizes 属性
  • 支持全屏展示
  • 支持全屏后缩放,并按需加载缩放后的分辨率
  • 移动端 100vw 宽度无边距
  • 自动将图片转化为 <figure> 并展示图片描述

视频

  • 自动解析 <iframe>src= 的内容并将其放在 srcdoc= 中减少网络请求
  • 可以实现在首页显示视频预览并自动静音播放(集成了 HLS.js

搜索

原本主题的搜索功能在电脑端只会在最右侧的边栏展示搜索结果,我对其进行了改进,实现了用户在搜索时搜索栏和搜索结果自动延长。各位可以直接前往首页体验,或者查看下方的效果视频:

网站搜索演示

分区解析与 CDN

我的网站目前同时部署在国内外多个主机上,使用着相同的配置。域名使用 Route 53 的延迟记录进行分区解析,并开启了 “运行状况检查” 实现宕机后自动切换服务器目前本站使用了 5 个服务器,分别部署在北京、东京(日本)和拉斯维加斯 (美国)、蒙特利尔 (加拿大) 和法兰克福 (德国)。

选择使用 Route 53 作为解析服务器的原因是:

  • 它使用了 Anycast 技术,在全球访问速度都很快
  • 国内连接 Route 53 的 DNS 服务器可以连接到延迟小于 50ms 的日本节点,
  • 支持 DNSSEC 和 IPv6
  • 支持按地区的分区解析、延迟解析等。在美国可以细分到州,其他地方也可以细分到国家
  • 支持 “运行状况检查”
  • 按量计费。起步价每个域名 $0.50 /月,“运行状况检查” 每个服务器 $0.50 /月。上述的所有功能也均是按量付费,没有固定月费。

视频 CDN

本站视频虽然是使用 Cloudflare Stream 存储和转码,但实际分发使用的是 CloudFront 和阿里云 CDN。主要是 Cloudflare 的视频是按量计费,其单价比 CloudFront 要贵。其次是 Cloudflare Stream 不提供国内节点,因此为国内提使用阿里云 CDN。

双 CDN 配置——Nginx 替换 CDN URL

实现双 CDN 有两种方法,第一种是使用 Nginx 根据访客国家替换 CDN URL。这样做相比分区解析的好处是即便用户配置的 DNS 服务器非用户所在地服务器,替换 CDN URL 方式依然会让用户使用正确的 CDN。可以采用了 Nginx 根据客户端 IP 的国家进行 CDN 域名的替换,具体配置——在 http 中:

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {    auto_reload 1d;    $geoip2_data_country_code default=CN country iso_code;}map $geoip2_data_country_code $tlo_domain {    default    "tlo.xyz";    "CN"       "tloxygen.com";}

server 中:

sub_filter '//videodelivery.net/' "//video.${tlo_domain}/";

这样一来,用户访问网站时,服务器会根据用户访问网站时的 IP 地址(而非 DNS 提供的 IP 地址)来选择合适的 CDN。

双 CDN 配置——分区解析

这就不用多说了,将两个 CDN 绑定在一个域名上,使用 GeoDNS 对不同地区的访客返回不同的结果。

图像 CDN

本站的图片均使用 Cloudflare Images 进行压缩与存储,并通过 Nginx 进行代理与缓存。Nginx 配置如下,实现了根据设备兼容性优先提供 AVIF、WebP 和 JPEG。这是因为 Cloudflare Images 在国内的速度不佳。此外 Cloudflare Images 可以在访问时自动将图片调整分辨率和格式。当用户访问相对路径 /cdn-cgi/imagedelivery/ 时,网站就会加载相应的图片,还省去了与新的域名建立 HTTP 连接的时间。

Nginx 配置

http 中:

map $http_accept $suffix {    default        "jpeg";    "~image/avif"  "avif";    "~image/webp"  "webp";    "~image/apng"  "apng";}map $http_accept $png_suffix {    default        "png";    "~image/avif"  "avif";    "~image/webp"  "webp";    "~image/apng"  "apng";}map $http_accept $gif_suffix {    default        "gif";    "~image/avif"  "avif";    "~image/webp"  "webp";    "~image/apng"  "apng";}map $http_accept $default_suffix {    default        "default";    "~image/avif"  "avif";    "~image/webp"  "webp";    "~image/apng"  "apng";}map $sent_http_Content_Type $file_name {    default        "default";    "image/avif"   "avif";    "image/webp"   "webp";    "image/apng"   "apng";    "image/jpeg"   "jpeg";    "image/png"    "png";    "image/gif"    "gif";}

server

proxy_store /var/www/images$uri/image.$file_name;location /cdn-cgi/imagedelivery/6T-behmofKYLsxlrK0l_MQ/ {    root /var/www/images/;    try_files $uri/image.$suffix $uri/image.$png_suffix $uri/image.$gif_suffix $uri/image.$default_suffix @proxy;}location @proxy {    proxy_ssl_name imagedelivery.net;    proxy_ssl_server_name on;    proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;    proxy_set_header Host imagedelivery.net;    proxy_set_header Upgrade $http_upgrade;    proxy_set_header Connection upgrade;    proxy_hide_header Upgrade;    proxy_hide_header Alt-Svc;    proxy_hide_header Expect-CT;    proxy_http_version 1.1;    proxy_set_header Connection "";    if ($uri ~* '^https://cdn.tlo.xyz/6T-behmofKYLsxlrK0l_MQ/(.*)$') {         add_header X-Cache-Status "MISS";        proxy_pass https://cdn.tlo.xyz/6T-behmofKYLsxlrK0l_MQ/$1;        break;    }}

通过 proxy_store,图片将会在第一次请求后永久的存储在本地,并在下次访问时从本地提供。在存储时,图片的变体名和格式会作为文件名的一部分进行存储。在访问时,服务器会根据客户端发送的 http_accept 请求头去查找对应文件。

AVIF 格式比 WebP 的压缩效率更好,而 WebP 格式比 JPEG 的压缩效率更好。然而对于兼容性而言,JPEG > WebP > AVIF。尽量不要在网站上使用 GIF,如果需要展示动画,可以使用静音自动循环播放的 <video> 代替。

WebP/AVIF 自适应之 CDN 配置

如果原站支持 WebP/AVIF 自适应,那么在配置 CDN 的时候,需要选择根据客户端的 Accept 头进行缓存。CloudFront 和阿里云 CDN 的配置分别如下:

CloudFront Accept 配置阿里云 CDN Accept 配置

自动部署

本站使用 GitHub Action 在服务器上运行 SSH 脚本实现自动部署。在服务器上配置了 post-merge 的 git hooks,在有改动后自动运行脚本。具体来讲,是在一个部署专用的服务器上生成静态页面,然后将这些静态页面分发到对应的服务器。

统计

本站使用自建的 Matomo网站统计。Matomo 是一个基于 PHP 和 MySQL 的非常强大的开源统计软件。

Matomo 后台管理界面截屏

除此之外,本站还通过 JavaScript 实现了对视频播放,图像查看和搜索的统计。本站还使用了 Nginx 的 post_action 功能实现了异步发送统计,具体在 server 中的配置如下:

location /api/a {    post_action @tracker;    return 204;}location @tracker {    internal;    proxy_pass https://origin/matomo.php$is_args$args;    proxy_set_header Upgrade $http_upgrade;    proxy_set_header Connection upgrade;    proxy_set_header Host matomo.tloxygen.com;    proxy_set_header TLO-Connecting-IP $remote_addr;}

HTTP/2 Server Push

本站还启用了 HTTP/2 Server Push,用户在访问网站时,服务器会一次性直接推送首屏渲染必要的 CSS 和 JS 文件,由于用户不需要在获取到 HTML 页面后再去获取 CSS 和 JS 文件,首屏渲染的时间大大缩短。实测在模拟 Fast 3G 环境下,启用 HTTP/2 Server Push 后首屏时间减少了约 0.3 秒:

仅启用 HTTP/2,首屏耗时 1.48 秒启用 HTTP/2 Server Push,首屏耗时 1.20 秒

具体 Nginx 中 server 的配置如下

listen 443 ssl http2;listen [::]:443 ssl http2;location ~* \.(?:html)$ {    http2_push /style/common/bulma.css;    http2_push /style/base.css;    http2_push /style/common/helper.css;    http2_push /style/post.css;    http2_push /style/widget-header.css;    http2_push /style/widget-post-list.css;    http2_push /style/themes/highlight-theme-light.css;    http2_push /js/common.js;    http2_push /js/sdk.latest.js;    http2_push /js/post.js;}

Azure DNS、NS1、Constellix,三家海外 GeoDNS 服务商对比

By: James Guo
15 November 2018 at 11:45

最近 DNSPod 的解析服务器宕机了一段时间,导致许多 DNSPod 用户的网站无法访问。本文将推荐几个提供 100% SLA 的海外 GeoDNS 服务,可用于替代不稳定的 DNSPod。并介绍一下使用多家 DNS 提供商来提高服务可用性的方法。

本文包括 Azure DNS、NS1、Constellix 的全面对比。

简介

这次推荐的三家 DNS 均是海外的支持 GeoDNS 的服务商,并都支持 Anycast。其中的 Azure DNS 和 NS1 在国内的速度都非常好,是直接走的香港/亚洲线路,平均延迟能够在 50ms 以内,不输国内 DNS 服务商。而这三家的海外速度都是极快的,可以秒杀 DNSPod、CloudXNS、阿里云解析等国内提供商。

关于 GeoDNS,精细度最好的是 Constellix:支持国家、省、市(包括中国的省、市),甚至是 AS 号(可以实现分运营商解析)、IP 段。NS1 支持国家、美国的州,也支持 AS 号、IP 段。至于 Azure DNS,通过使用 Traffic Manager,可以支持国家、部分国家的州、IP 段。由于都支持 IP 段,所以理论上支持任意精度的 GeoDNS 了。

至于价格,NS1 提供了免费额度(每月 500k 请求),对于小流量网站而言是够用的,可一旦超出这个免费额度,那么收费是很高的:**$8/百万个请求**。相比而言,Azure DNS 和 Constellix 的价格都很便宜了,其中 Constellix 有 $5/月 的起价。

使用多家 DNS 服务商

同时使用多家 DNS 服务商是可行的,只要使用服务商的 DNS 记录保持相同即可。这要求所使用的服务商能够配置主域名的 NS 记录(建议但不是必须)。这次介绍的 Azure DNS、NS1、Constellix 三家,以及以前介绍过的 Route 53、Google Cloud DNS、Rage4、阿里云解析均可配置主域名的 NS 记录(其中阿里云解析和 Azure DNS 只能额外添加第三方记录;其他几家可以完全自定义 NS 记录)。而 Cloudflare 以及国内的 DNSPod、CloudXNS、阿里云解析由于不能配置主域名下的 NS 记录,意味着你不能很好的进行 DNS 混用。

要使用多家 DNS,有两种实现方法:主服务商和从服务商方式以及两个主服务商方式。完成配置后,将多家的 NS 服务器配置到权威 NS 记录以及域名注册商下的 NS 列表。

使用两家服务商会增加配置难度,但可以提高 DNS 服务的稳定性。如最近的 DNSPod 宕机以及 2016 年的 Dyn 宕机所导致的众多网站无法访问,均是因为众多网站仅使用了一家 DNS 提供商。如果使用了多家 DNS 提供商,则网站仅会在所使用的所有服务商均发生宕机事故时才会无法访问,而这显然发生概率很小。

主服务商和从服务商

要想这样配置,需要从服务商支持使用 AXFR 从主服务商获取记录,还需要主服务商也支持 AXFR 传输。其中,NS1、Constellix 均可作为主服务商或从服务商,意味着你可以同时使用这两家,并选择任何一家作为主服务商,另一家作为从服务商。

两个主服务商

你也可以使用两个主服务商,并保持所有的记录(包括主域名下的 NS 记录)相同(建议,但不是必须)。建议也将 SOA 的序列号同步。

样例

github.com. 这个域名就同时使用了 Route 53 和 DYN 的服务。这可以使用 dig 工具验证。

$ dig github.com ns +short  ns1.p16.dynect.net.  ns2.p16.dynect.net.  ns3.p16.dynect.net.  ns4.p16.dynect.net.  ns-1283.awsdns-32.org.  ns-421.awsdns-52.com.  ns-1707.awsdns-21.co.uk.  ns-520.awsdns-01.net.

经检验,在两家 DNS 服务商也配置了相同的记录。

$ dig @ns1.p16.dynect.net. github.com a +short  13.229.188.59  13.250.177.223  52.74.223.119  $ dig @ns-1283.awsdns-32.org. github.com a +short  13.229.188.59  13.250.177.223  52.74.223.119  

下面逐个介绍一下这三家 DNS 提供商。

所有 DNS 测评一览(还包括 CloudXNS、Route 53、Cloudflare、Google Cloud DNS、Rage4 以及阿里云解析)

Azure DNS

微软 Azure 产品线下的 DNS 服务。使用 Anycast 技术,并且国内能够直接连接到香港/亚洲节点,所以速度很快。

值得注意的是,类似 Route 53,Azure 所分配的四个服务器使用的是不同的网段、不同的线路,可能有更高的可用性。

注意:Azure 的 DNS 的分区解析可能不兼容 IPv6,这意味的解析结果可能会被 Fallback 到默认线路。

  • 国外速度:★★★★☆,36 ms
  • 北美速度:★★★★☆,27 ms
  • 亚洲速度:★★★★☆,39 ms
  • 欧洲速度:★★★★☆,29 ms
  • 国内速度:★★★★☆,49 ms
  • 最短 TTL:0s
  • 国内分区解析:★★★★★,支持配置到中国,支持 IP 段配置(配合 Traffic Manager)
  • 国外分区解析:★★★★★,支持配置到大州、国家以及部分国家的州,支持 IP 段配置(配合 Traffic Manager)
  • DNSSEC:不支持
  • IPv6:支持
  • 记录类型:支持 A、AAAA、CNAME、NS、MX、TXT、SRV、CAA、PTR。
  • 根域名 CNAME 优化:不支持
  • 优先级:支持(配合 Traffic Manager)
  • 自定义 NS:仅支持添加额外的 NS
  • 价格:每个域名 $0.5/月,**$0.4/百万个请求**
  • 用例 A 价格:**$0.90**
  • 用例 B 价格:**$10.50**
  • SLA:100%

NS1

NS1 也使用了 Anycast 技术,并且国内能够直接连接到香港/亚洲节点,所以速度很快。

  • 国外速度:★★★★★,23 ms
  • 北美速度:★★★★★,9 ms
  • 亚洲速度:★★★★☆,40 ms
  • 欧洲速度:★★★★★,20 ms
  • 国内速度:★★★☆☆,65 ms
  • 最短 TTL:0s
  • 国内分区解析:★★★★★,支持配置到中国,支持 IP 段配置。
  • 国外分区解析:★★★★★,支持配置到大州、国家、美国的州,支持 AS 号、IP 段配置。
  • DNSSEC:支持
  • IPv6:不支持
  • 记录类型:支持 A、AAAA、AFSDB、CAA、CERT、CNAME、DS、HINFO、MX、NAPTR、NS、PTR、RP、SPF、SRV、TXT。
  • 根域名 CNAME 优化:支持
  • 优先级:支持(配合 Traffic Manager)
  • 自定义 NS:仅支持添加额外的 NS
  • 价格:每月前 500k 请求免费,超出部分 $8.0/百万个请求
  • 用例 A 价格:**$4**
  • 用例 B 价格:**$156**
  • 用例 C 价格:**$156**
  • SLA:100%

Constellix

此 DNS 以 GeoDNS 优势著称,使用了 Anycast 保证最低的延迟。

Constellix 三组有六个 DNS 服务器,每一组使用了不太相同的线路。

  • 国外速度:★★★★☆,31.51 ms
  • 北美速度:★★★★★,9.81 ms
  • 亚洲速度:★★★★☆,48.87 ms
  • 欧洲速度:★★★★★,23.77 ms
  • 国内速度:★★☆☆☆,108.9 ms
  • 最短 TTL:0s
  • 国内分区解析:★★★★★,可以精确到每一个省、市,可以配置 ASN 以实现运营商分区解析。
  • 国外分区解析:★★★★★,精确到了各个国家、省、市
  • DNSSEC:不支持
  • IPv6:支持
  • 记录类型:更加齐全,只支持 A、AAAA、CNAME、NS、MX、TXT、SRV、HINFO、NAPTR、CAA、CERT、PTR、RP、SPF。
  • 根域名 CNAME 优化:支持
  • 优先级:支持
  • 自定义 NS:支持
  • 价格:第一个域名 $5/月,此后每个域名 $0.5/月。**$0.4/百万个请求**。分区解析 $0.6/百万个请求
  • 用例 A 价格:**$5.39**
  • 用例 B 价格:**$14.90**
  • 用例 C 价格:**$19.30**
  • 统计功能:支持,可以看到每个国家、城市的请求数。甚至还可以启用日志,看到每一个请求的客户端 IP、IP 数据包类型等等。
  • SLA:100%

Cloudflare Argo 与 Railgun 对比测试,CDN 加速的黑科技

By: James Guo
20 May 2017 at 19:52

本网站曾经一直将国外解析到 CloudFront 实现为国外加速,最近看到 Cloudflare 支持了 Argo 这一新功能,于是就把国外的 CDN 从 CloudFront 换到了 Cloudflare 并开启了 Argo 来试一下效果,官方宣称无缓存时能明显降低 TTFB(首字节延迟),有缓存时也能提高缓存命中率。本文还会将其与 Cloudflare 的另一个企业级的 CDN 加速黑科技——Railgun 进行对比。

Cloudflare Argo

提升缓存命中率,Argo Tiered Cache

Cloudflare 的节点很多,但是节点太多有时不是一件好事——大多数 CDN 之间的节点是相对独立的。首先要先明白 CDN 的工作原理,CDN 通常不会预先缓存内容,而是在访客访问时充当代理的同时对可缓存的内容缓存。就拿本站来说,本站用的是香港虚拟主机,如果有英国伦敦的访客访问了我的网站,那么由于我的网站是可被缓存的,他就会连接到伦敦的节点并被缓存在这个节点。那么如果是英国曼彻斯特的访客访问了呢?由于 CDN 在曼彻斯特另有节点,访客会直接连接到曼彻斯特节点,然而曼彻斯特上并没有缓存,所以该节点会回源到香港。而显然的是,如果曼彻斯特回源到伦敦,使用伦敦的缓存会更快。 综上,如果能选择性的从其他节点上获取资源,TTFB 会更低,缓存命中率也会相应提高。但是一般的 CDN 不会去这样做,因为节点相互独立,节点之间并不知道对方是否已经缓存。一般的解决方法是节点与源站之间先经过为数不多的几个节点,这几个节点可能只是分布在几个州,比如整个欧洲就只有一个这种节点。这样的话,伦敦的访客访问后,同时也被欧洲的那个节点缓存。这样,当再有欧洲其他地区的访客连接到一个没有缓存的节点时,这些节点会直接提供欧洲的那个节点的缓存。CloudFront 和 KeyCDN 就利用了这样的技术。 Cloudflare 是如何实现的他们官方没有详细说明。然而在实际测试时,并没有观察到缓存率上有明显提升,远比不过 CloudFront 的效果。下图是通过这些节点测试的 TTFB,请求是逐个发起的。

Cloudflare 上可被缓存的内容的首次访问测试,启用了 ArgoCloudFront 对比,比 Cloudflare 要强

降低 TTFB,Argo Smart Routing

通常情况下,节点与源站的连接是直接的,这之间的网络很大程度上取决于主机的网络接入。然而,有了 Argo Smart Routing,Cloudflare 会使用自己的线路。图片来自 Cloudflare.com。

Argo Smart Routing 动态图

国外请求测试地址,其中的 via 字段就是 Cloudflare 与本站建立的连接的 IP 地址。通过 GeoIP 服务查询,发现是香港的 IP。Cloudflare 将自己的节点之间都建立了长连接,并在离源站最近的服务器上与源站也提前建立了连接。这样,就能大大降低首次连接所需要的时间。如果回源是 HTTPS 的,那么效果更明显。我的另一个测试地址是没有开启这个功能的,用来对比,它的回源与本站建立的 IP 就不是香港的。

使用 Flexible SSL 的 TTFB 对比

没有启用 Argo启用了 Argo

使用 Full SSL 的 TTFB 对比

没有启用 Argo 并且是 Full SSL启用了 Argo 并且是 Full SSL

速度的确有一定的提升,但是不是特别明显,而且似乎开启了之后一些节点反而更不稳定——原本都是比较稳定的一个速度,开了这个之后一些节点反而忽快忽慢。看来提速的最佳方法还是半程加密。

Cloudflare Railgun

Railgun 是 Cloudflare 专门为 Business 和 Enterprise 企业级客户提供的终极加速方案。要使用它,先需要升级网站套餐为 Business 或 Enterprise,然后还需要在服务器上安装必要软件并在 Cloudflare 上完成配置。这相当于是一个双边加速的软件,其实现原理是让服务器与 Cloudflare 建立一个长久的 TCP 加密连接,使用 Railgun 独有协议而不是 HTTP 协议,这样显然能减少连接延迟。此外,它还会对动态页面缓存:考虑到大多动态页面都包含了大量相同的 HTML 信息,在用户请求一个新的页面时,服务器将只发送那些变化了的内容。这相当于一种多次的 Gzip 压缩。

开启 Railgun 截图

官方宣称,使用 Railgun 能够实现 99.6% 的压缩率,并实现两倍的速度。实际体验也确实如此:

启用了 Railgun 并且是 Full SSL

Railgun 的加速效果还是非常之明显的,明显强于 Argo。

总结

Argo 并没有想象中的那么好用,而且 $5/mo 的起步价和 $0.10/GB 的流量并不便宜。当然也有可能需要一段时间 Argo 去分析线路延迟才能更好的进行优化。本文预计将在一个月后补充更新。 Railgun 效果还是极其显著的,但是它需要企业版套餐才能够使用,并不亲民。

动态内容

延迟:Google Cloud CDN 延迟最低,Cloudflare Railgun 仅次。 流量:对于普通的动态 CMS,Cloudflare Railgun 大约能节省 10 倍以上流量,Google Cloud CDN 是做不到的。 我在国内外几家全站 CDN 对比中测试 Google Cloud CDN 时,其极低的 TTFB 令我惊讶,仔细研究后发现节点是与主机之间建立长连接,而且会保持很长一段时间,此外所有网络都走 Google 内网,本质上与 Argo 和 Railgun 类似。所以目前服务动态内容最快的应该还属 Google Cloud CDN 了,Railgun 基本与之相当。

静态内容

CloudFront 自带的 Regional Edge Caches 在缓存静态内容提高缓存命中率上要比 Argo Tiered Cache 和 Railgun 好,但是 Argo Smart Routing 在服务于动态的不可缓存的内容上更显出优势。Railgun 和 Google Cloud CDN 除了会在边缘节点缓存之外没有其他专门的优化。

关于本站的分区解析

本站的解析没有使用 Cloudflare 而是 自建的 DNS,因为我的 Cloudflare 域名是通过 CNAME 接入的。Cloudflare 分配的 IP 在很长时间内都不会变动,所以我直接把其 IP 设置为了海外线路。使用自建的DNS是为了在备案后,为国内分区解析配置 CDN 线路。 PS: 大家应该都知道启用这个功能后并不会提升国内连接 Cloudflare 的速度,如果想要用 Cloudflare 并且希望国内快一点,源站最好就用美国西岸的。

国内外几家全站 CDN 对比

By: James Guo
30 January 2017 at 08:00

配置全站 CDN 可以缓存 HTML 页面和加快页面首次加载所耗时间。本文重点讲述 WordPress 的全站缓存,国内外 CDN 混用的解决方案,以及让页面也在 CDN 上缓存的正确做法。本文主要介绍 CloudFront,同时也对 Cloudflare、又拍云、百度云加速、KeyCDN、Google Cloud CDN 这几家 CDN 进行对比。

全站 CDN 能在哪些地方加速?

我已经像你之前一样只缓存了图片、视频、CSS 和 JS 之类的静态资源,全站 CDN 有什么优点?

就算不缓存任何内容,全站 CDN 也是有他的优点的:

  1. SSL 卸载:源站到 CDN 之前走 HTTP 传输,CDN 到用户走 HTTPS 传输。这样,能减轻源站原本因为 SSL 所造成的硬件负担。然而,由于源站到 CDN 的传输是明文的,仅建议全程内网的情况,或线路可控的情况下使用,否则有很大的安全隐患。然而几乎所有的 CDN 也可以配置源站到 CDN 之间走 HTTPS 加密传输。
  2. 安全防护:所有的 CDN 都自带基于第一、二、三层网络的防护(防止 SYN 攻击),大多数还带了第七层的防护(防止 CC 攻击)。
  3. 减少延迟:建立 HTTP 连接之前需要先进行 TCP 和 HTTP 的 SSL 握手,这样会增加首次加载所需时间。而很多 CDN 都会与服务器进行预连接,而且 CDN 的服务器离用户较近,所以能减少首次加载所需时间,即使没有缓存页面。
  4. 缓存动态页面:所谓动态页面,其实大多数对于没有登录的用户来说内容其实是固定的(如 WordPress 的文章页),所以可以针对未登录的用户缓存。这需要 CDN 能自动根据 Cookie 判断用户有没有登录,这下就只剩 Cloudflare 企业版和 CloudFront 可以做到了。

使用 CloudFront 作为全站 CDN

CloudFront 有 Amazon 自建的网络,单价较高但是 0 元起步,适合中小客户。本文将重点介绍 CloudFront 和 WordPress 配合实现动静分离,缓存 HTML 页面。之后将对比其他的一些 CDN。

  • 国外速度:★★★★☆,节点数量众多,但相比 Cloudflare 要差一些,并且不支持 Anycast。
  • 国内速度:★★★☆☆,国内开始走亚洲节点,速度要比 Cloudflare 快
  • 可定制性:★★★★★,可以根据不同的路径回源使用不同的服务器,甚至回源到不同的服务器,且没有规则数量上限。此外,配合 Lambda@Edge 甚至可以将原本需要源站响应的动态内容交给缓存服务器做,只需使用 Node.js。
  • 廉价指数:★★★☆☆,从免费起,Pay-as-you-go,单价确实高,但是可以通过价格级别牺牲速度来换取更低廉的价格
  • 方便接入:★★☆☆☆,需要配置各种缓存参数才能使用,NS 接入并不直接,CNAME 接入相比 NS 更有难度。SSL 证书首次也需要手动申请,但自动续签。
  • 缓存命中:★★★★☆,支持 _Regional Edge Caches_,先缓存到全球的 9 个节点,再向下分发,大大提升缓存命中率
  • 动静分离:★★★★★,自动分离,一个服务下可以根据不同目录设置不同 Behaviors,甚至配置多个源站服务器,支持匹配 Cookie、GET、Header 规则缓存,支持禁用 POST 等提交方式
  • 缓存刷新:★★★★☆,支持单个 URL 刷新以及规则匹配刷新
  • 接入方式:NS/CNAME
  • 证书兼容性:默认仅限支持 SNI 的浏览器,可额外购买服务($600/月)以兼容所有浏览器。

CloudFront 作为全站 CDN 的特性:

  • 支持根域名
  • 缓存静态文件
  • 缓存页面
  • 页面更新自动清理缓存
  • 免费 SSL 证书
  • 可配置国内外 CDN 混用

使用方法

先去 CloudFront 控制面板,点击 “Create Distribution”,选择 “Web”,然后进行类似如下的配置。源站配置注意 Origin Domain Name 必须是完整域名,而且如果用了 HTTPS,那么那个域名下必须有配置有效证书。

CloudFront 基础配置截图

缓存配置,我把 Host 加入了 Header 白名单,Cookie 要添加 wordpress*wp* 到白名单。

CloudFront 详细配置截图

然后前端配置,证书点 “Request or Import a Certificate with ACM” 就能申请 Amazon 颁发的证书了。CNAMEs 下填写你的网站的域名。

CloudFront 前端配置截图

注意,创建后可能要等不到一小时才能被访问到。 为了根域名和 CloudFront 配合使用,我还得换 Route 53 这个 DNS 解析。由于这是精度非常高的 GeoDNS,是需要将解析服务器向各大 DNS 缓存服务器去提交,让这些缓存服务器去针对你的 DNS 缓存服务器加入到启用 EDNS Client Subnet 的白名单中。还好 Route 53 是最流行的 GeoDNS 之一,所以如果你用它给的 NS 记录,而不去自定义,就不用操心这个了。在配置根域名时,直接选择 A 记录,然后开启 Alias,填写 CloudFront 域名就行。如果想要支持 IPv6,那就再建一个 AAAA 记录即可。这样的话如果你从外部解析,你会直接解析到 A 记录和 AAAA 记录,而不是 CNAME 了!

CloudFront 配合 Route 53 使用截图

此时,CloudFront 就配置完了。现在 CloudFront 会自动缓存页面约一周的时间,所以需要配置文章更新时清理缓存。我写了一个插件,可以在有文章更新/主题修改/内核更新时清理所有缓存,新评论时清理文章页面,控制刷新频率为 10 分钟(这是由于 CloudFront 刷新缓存的速度是出奇的慢,而且刷新缓存只有前一千次免费)。欢迎使用我制作的插件。 不过,CloudFront 在国内的访问速度还不如我之前用的 GCE,这可怎么办?没关系,Route 53 可以 GeoDNS,我把中国和台湾还是解析到了原本的 GCE 上,这样速度其实只提不减。注意,若要这样做,原本的服务器也要有有效证书(同理,你要是域名已经备案,则可以设置为国内的 CDN 的 IP,达到国内外 CDN 混用的效果)。CloudFront 会影响 Let’s Encrypt 的签发,所以需要通过设置 Behaviors 和多个源站服务器,来继续实现 80 端口的文件认证。实际测试 Route 53 为中国解析的 IPv4 识别率为 100%,IPv6 的识别率欠佳。

CloudFront 配合 Route 53 使用截图 2

实际使用情况

GeoDNS 效果测试

国内解析情况:

$ dig @8.8.8.8 +short guozeyu.com a104.199.138.99$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:2029:3c00:9:c41:b0c0:93a12600:9000:2029:9600:9:c41:b0c0:93a12600:9000:2029:2a00:9:c41:b0c0:93a12600:9000:2029:1600:9:c41:b0c0:93a12600:9000:2029:c00:9:c41:b0c0:93a12600:9000:2029:ce00:9:c41:b0c0:93a12600:9000:2029:6400:9:c41:b0c0:93a12600:9000:2029:ac00:9:c41:b0c0:93a1

国外解析情况:

$ dig @8.8.8.8 +short guozeyu.com a52.222.238.23652.222.238.22752.222.238.20752.222.238.10752.222.238.20852.222.238.7152.222.238.6852.222.238.67$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:202d:5c00:9:c41:b0c0:93a12600:9000:202d:ec00:9:c41:b0c0:93a12600:9000:202d:7c00:9:c41:b0c0:93a12600:9000:202d:2a00:9:c41:b0c0:93a12600:9000:202d:9400:9:c41:b0c0:93a12600:9000:202d:c600:9:c41:b0c0:93a12600:9000:202d:f600:9:c41:b0c0:93a12600:9000:202d:6200:9:c41:b0c0:93a1

没错,CloudFront 分配给的 IP 数量就是多,让别人看了会感觉很厉害。

Ping 启动前后对比

这里只对比国外的速度

源站速度CDN 速度

HTTPs Get 启动前后对比

这里也是只对比国外的速度

源站速度CDN 速度

启动 CDN 后的 TTFB 几乎全面绿色,建立 TCP 和 TLS 的时间显著降低。

Amazon 的 SSL 证书

CloudFront 免费签发的 SSL 证书是多域名通配符证书(Wildcard SAN),并且主要名称是自定的,要比 Cloudflare 的共享证书高级。此类证书在 Cloudflare 上需要花费每月 10 美元。此类证书在市面上很难买到,而且价格取决于域名数量,在一年几千到几万不等。 然而,这个证书只能在 AWS 的 CloudFront 和负载均衡器上使用。

Amazon 证书

CloudFront 的证书链较长,会影响 TLS 时间,不过由于它同时也是 CDN,这样 TLS 时间几乎减少到了可以忽略不计的程度。主要还是因为 macOS 上还没有直接信任 Amazon Root CA,如果直接信任了,就用不着这样了。

其他 CDN 厂商对比

以下列出的所有提供商(或某一提供商的某些版本),均符合以下条件,如果不符合则单独列出:

  1. 是个 CDN 厂家
  2. 支持 HTTPS、HTTP/2
  3. 免费签发 SSL 证书,且自动续费
  4. 我现在正在使用,或曾经长期使用过,或深入了解过
  5. 可以给 WordPress 全站 CDN 加速

Cloudflare 免费版/专业版

有自建的网络,最快的速度、最低廉的价格,主要提供网站安全防护,当然还附带了 CDN。其提供的 NS 服务也是(国外)业界第一的速度。本站国外使用了 Cloudflare,欢迎直接测试本站国外的速度。

  • 国外速度:★★★★★,由于拥有众多的海外节点并支持 Anycast,给满分。速度指标指全球各地的 Ping 值,下同
  • 国内速度:★★☆☆☆,国内走美国西岸的节点,速度欠佳
  • 可定制性:★★★★★,需要使用 Page Rules 进行基础定制,还可以使用 Worker 进行编程定制。
  • 廉价指数:★★★★★,从免费起步,给满分
  • 方便接入:★★★★★,改完 NS 直接接入,自动签发 SSL 证书,无需服务器配置,还有比这更简单的吗?
  • 缓存命中:★★★★★,由于节点数量实在众多,于是在每一个地方都需要单独缓存,所以缓存命中率很低;但是如果开启了 Argo,那么就能够实现更高的缓存命中率,此外还能自动调配最优线路。Argo 需要每月额外的消费($5/mo + $0.10/GB)。
  • 动静分离:★★★☆☆,自动分离,它遵守 Cache-Control 规则,也可以设置 Page Rules 修改默认缓存规则。但是,默认不缓存 HTML 页面、Page Rules 只有 3 个的限制、以及没有开放匹配 Cookie 规则的缓存。
  • 缓存刷新:★★☆☆☆,仅支持刷新某个页面的 URL 和刷新全部内容,不支持规则刷新
  • 接入方式:NS(如果是 Partner 则可以有免费的 CNAME 接入)
  • 证书兼容性:仅限支持 SNI 的浏览器

Cloudflare 作为全站 CDN 的特性:

  • 支持根域名
  • 缓存静态文件
  • 不支持缓存页面
  • 免费 SSL 证书

有一点不同的是,Cloudflare 签发的是共享证书,证书样式如下:

Cloudflare 共享证书

我觉得 Cloudflare 签发共享证书有两个原因,一是历史遗留问题:Cloudflare 专业版的 SSL 证书服务是支持无 SNI 的客户端的,而为了支持无 SNI 的客户端,一个 IP 就只能配置一个证书,所以就使用了共享证书节约 IP 资源。而现在免费版也有了 SSL,虽然免费版使用了 SNI 技术,但是证书总不能比付费版本还要高级吧,于是还是使用了共享 SSL 证书;二是为了增加更多的增值服务,现在 Cloudflare 上可以购买 Dedicated SSL Certificates,实现独立的证书(如果是付费版本启用,不支持 SNI 的客户端仍然 Fall back 到共享证书,所以仍然兼容不支持 SNI 的设备)。

Cloudflare 企业版

简介同上,此版本适合大客户,流量越大越适合用。百度云加速是和 Cloudflare 深度整合的,其实基础设施完全一样,但百度云加速没有提供 API 接口。

  • 国外速度:★★★★★,同上
  • 国内速度:★★★★★,有众多的国内节点
  • 可定制性:★★★★★,同上,Page Rules 数量有所提升
  • 廉价指数:★★☆☆☆,每月固定的花销,不是按需付费,量越大越实惠
  • 方便接入:★★★★★,同上
  • 缓存命中:★★★★★,同上
  • 动静分离:★★★★☆,对于 WordPress 来说安装了官方插件就可以自动分离,相比免费版,他有更多的 _Page Rules_、支持匹配 Cookie 规则缓存,相比 CloudFront 差一些
  • 缓存刷新:★★★★☆,相比免费版,支持了 Cache-Tag 刷新规则,然而需要服务端的配置
  • 接入方式:NS/CNAME
  • 证书兼容性:所有浏览器

Cloudflare 企业版作为全站 CDN 的特性:

  • 支持根域名
  • 缓存静态文件
  • 支持缓存页面
  • 页面更新自动清理缓存(完美清理缓存)(由于百度云加速没有提供 API,所以云加速没有这个功能)
  • 强大的 DDOS 防御以及 WAF 功能
  • 免费 SSL 证书

UPYUN

使用自己管理的机房,网络有些受限于中国的环境,单价业界最低。

  • 国外速度:★★☆☆☆,北美洲、欧洲、亚洲都有一定数量的节点,但速度欠佳。且 CNAME 接入所用的 NS 在国外没有节点,在解析速度上就牺牲很多。
  • 国内速度:★★★★★,国内节点很多,但是由于只能 CNAME 接入,需要多一次解析请求,花费时间
  • 可定制性:★★★★☆,可以设置很多个缓存规则,并且有自定义 Rewrite,可以实现比 Rewrite 更丰富的功能,但是函数功能受限。
  • 廉价指数:★★★★½,从免费起,Pay-as-you-go,价格也是一降再降,业界较低的标准
  • 方便接入:★★★☆☆,不需要配置多少参数,CNAME 接入相比 NS 更有难度。SSL 证书首次需要手动添加,自动续签。
  • 缓存命中:★★★★½,有源站资源迁移功能,首次访问后直接永久缓存。但是如果要删除文件,还需要用 API 手动删除,扣半分
  • 动静分离:★★★★☆,自动分离,可以配置不同目录的缓存规则,但是不支持Cookie 规则缓存
  • 缓存刷新:★★★★☆,支持单个 URL 刷新以及规则匹配刷新
  • 接入方式:CNAME,所以不能根域名使用
  • 证书兼容性:仅限支持 SNI 的浏览器

UPYUN 作为全站 CDN 的特性:

  • 不支持根域名
  • 缓存静态文件
  • 不支持缓存页面
  • 有 WAF 功能
  • 免费 SSL 证书
  • 可配置国内外 CDN 混用

UPYUN 和下面的 KeyCDN 签发的都是 Let’s Encrypt 的独立证书,但都是单域名证书,甚至有 www 和无 www 的都要单独申请。

Google Cloud CDN

有全球最密集的网络集群,最快的速度、较低的单价,主要提供负载均衡,SSL 卸载,当然还附带了 CDN。由于缓存命中率低,需要超大型访问量的网站才有效。正是因为这一点,Google 自己只是将用户量极大的搜索服务用上了这个 CDN 系统,其余的很多 CDN 用的是 Cloudflare 和 Fastly 的。Google 的网络和 Cloudflare 和 Fastly 的网络有内网链接。详细介绍看本站的这篇文章

  • 国外速度:★★★★★,由于拥有众多的海外节点并支持 Anycast,给满分。
  • 国内速度:★★★☆☆,国内直连香港节点,几乎是速度最快的香港网络的,与国内几大运营商都有接入,但毕竟没有国内节点,比不过一些国内的速度。(但是目前所分配到的一些 IP,联通会绕道至美西了)
  • 可定制性:★★☆☆☆,可以根据不同路径配置不同的服务器,然后,好想也没什么别的可定制的了。
  • 廉价指数:★★☆☆☆,由于占用了 IP 资源,每月需要花费 18 美元的固定价格,并还需要再为流量付费。流量的单价较低。
  • 方便接入:★☆☆☆☆,需要各种复杂的配置,但是一旦完成了配置,就同时有了负载均衡,弹性伸缩等等特性。
  • 缓存命中:★½☆☆☆,节点太多,小流量网站都很难遇到命中的情况。但可以利用跨区域负载均衡提高缓存命中率。
  • 动静分离:★★☆☆☆,自动分离,但不能配置任何规则。
  • 缓存刷新:★★★★☆,支持单个 URL 刷新以及规则匹配刷新
  • 接入方式:IP 绑定,它直接给你分配一个独立的 Anycast IP,只需要 A 记录解析即可。
  • 证书兼容性:所有浏览器
  • 不包含免费 SSL,需要自己购买

Google Cloud CDN 作为全站 CDN 的特性:

  • 支持根域名
  • 缓存静态文件
  • 不支持缓存页面
  • 免费 SSL 证书
  • 可配置国内外 CDN 混用

KeyCDN

他们是租用别人的独立服务器,提供一体化 CDN 服务,单价业界最低。

  • 国外速度:★★★★☆,和 CloudFront 有一拼,但是由于只能 CNAME 接入,需要多一次解析请求,花费时间
  • 国内速度:★☆☆☆☆,国内的话香港节点,但是狂绕道,反而比美国还慢
  • 廉价指数:★★★☆☆,有最低年费(相当于起步价)
  • 方便接入:★★★½☆,不需要配置多少参数,CNAME 接入相比 NS 更有难度。SSL 可以一键添加。
  • 缓存命中:★★★★☆,有类似 CloudFront Regional Edge Caches 的功能
  • 动静分离:★★☆☆☆,自动分离,但不能配置规则。支持针对 Cookie 的缓存配置,但不能匹配 Cookie 内容
  • 缓存刷新:★★★★☆,支持单个 URL 刷新、全部刷新、Cache-Tag 刷新
  • 接入方式:CNAME,所以不能根域名使用
  • 证书兼容性:仅限支持 SNI 的浏览器

KeyCDN 作为全站 CDN 的特性:

  • 不支持根域名
  • 缓存静态文件
  • 缓存页面
  • 页面更新自动清理缓存(完美清理缓存)
  • 免费 SSL 证书
  • 可配置国内外 CDN 混用

我为他写了一个插件可以实现完美清理缓存,详情见此

关于 WordPress 动静分离的新方法

WordPress 可以分别设置 Site URL 和 Home URL,对于 https://example.com 这个网站,这两栏就可以这样设置:

然后,直接给 Home URL 上 CDN,在 CDN 或者源站上配置忽略 Cookie 信息。Site URL 回源,用作 WordPress 后台管理即可。

Cloudflare 的全新功能体验——Load Balancing、Rate Limiting

By: James Guo
4 October 2016 at 09:26

Cloudflare 在 2016 年末终于增加了两个重磅的功能,分别是:

  • Load Balancing(原名:Traffic Manager)
  • Rate Limiting(原名:Traffic Control)

Load Balancing 支持更加高级的负载均衡功能,并终于支持了大家很需要的跨区域负载均衡功能;Rate Limiting 支持了高级的访问次数限制功能。越来越多的原本需要在服务器上配置的功能,现在在 Cloudflare 上也能进行配置了。(目前这两个功能还属于 Beta 阶段,需要认证用户才能使用)

Load Balancing

此功能可以把 Cloudflare 当作负载均衡器使用,而不需要再在主机提供商上配置负载均衡,官网介绍。目前此功能仅向 Enterprise 账户和部分有资格的用户开放。该功能有两种实现方式,分别如下:

通过 Cloudflare 的 CDN 实现(Anycast)

负载均衡的功能是在 Cloudflare 的边缘服务器上实现,是通过第 7 层反代的方式实现,其实很类似于原本的 CDN 功能,不过回源可以高度定制。源站可以配置多个地区(需手动设置服务器的位置),每个地区也可以配置多个服务器,可以将这些众多服务器设置为一个 Group。将域名指向这个 Group,然后 Cloudflare 的边缘服务器的回源可以根据服务器的地区来自动选择最近的源站服务器。这样可以非常有效的降低首字节的延迟,对动态资源速度的提升会有很大的帮助。

可配置服务器的地区 (两种方式一样)

此外,Cloudflare 还自带了 Health Check 功能,可以当服务器宕机后能够自动更改回源。虽然通过 DNS 的方式也可以实现宕机后切换,但是 DNS 方式毕竟会收到缓存时长影响,若使用 CDN 切换,则可以实现秒级切换。 我的一个 WordPress 站点 tlo.xyz 就使用了这个功能,默认是美国东部和亚洲东部跨区域负载均衡,两者有一者宕机自动切换。如果全部宕机,则 fallback 到 Google Cloud Storage 上的静态页面。你可以观察 https://tlo.xyz 上的 TLO-Hostname 的 Header 来判断是哪一个服务器做的响应。

Load Balancing 截图

通过 DNS 实现(GeoDNS + 权重)

使用此功能不需要开启它的 CDN 功能,故访客是直接连接源站的。同上一种方式也是配置一个 Group,只是不开启 CDN 功能,然后 Cloudflare 会只作为 DNS 服务器的功能。它会自动进行 GeoDNS,给访客返回最近的服务器的 IP 地址,同样也支持 Health Check 功能,当服务器宕机后会自动切换解析。 不同于其他的 DNS 解析商,Cloudflare 真正做到了智能,只需要配置一个 Group 即可,剩下的 Cloudflare 会自动搞定,而不是去手动地选择哪一个地区解析到哪一个服务器。 此功能已经被我测试,目前的测试期间,GeoDNS 的定位功能是根据请求最终抵达的 CloudFlare 的服务器来决定的,也就是说是依靠 Anycast 系统来决定的。然而中国用户绝大多数会被运营商定向到 CloudFlare 的美国西部服务器,于是就会被 GeoDNS 系统解析道美国西部位置所对应的结果。所以此功能还是十分有限,不适合国内使用。

Rate Limiting

Cloudflare 终于可以限制 IP 的请求速率,此功能能够相当有效的过滤 CC 攻击,而且对于普通访客几乎没有影响(以前只能通过 I’m under attack 功能实现,然而这个功能会让所有用户等 5 秒才能载入)。它可以根据不同的路径配置不同的请求速率,能够实现防止暴力破解密码、防止 API 接口滥用等功能。

为何要使用一个 CDN 服务?

By: James Guo
10 January 2016 at 15:00

CDN(内容分发网络)是一种网站服务,可以让用户从周围最近的服务器上获取静态的内容(尤其是图像、视频、音频、CSS 和 JavaScript),服务器尽可能地遍布全球各地。一个 CDN 网络,说白了就是一堆会自动缓存的代理服务器。 那么,使用 CDN 有什么好处呢?首先,就是可以减少延迟。我的服务器在美国,从北京到美国的通信一次往返大约要 300ms,当我使用了 (有中国服务器的)CDN 之后,通信一次往返就只需要不到 10ms 了。除此之外,CDN 还能有效的减少下载时间,因为某些国家会控制网络流量的出口带宽,当使用了内地的服务器后,速度就能明显提升。

CDN 的工作原理

通常,你并不需要将文件上传到 CDN,你只需要将域名解析到对应的服务器。当用户访问你的网站时,就相当于访问到了这个服务器。这个服务器会检查是否有缓存,若有,那么会直接从这个缓存返回给你;如果没有,则会去从原始服务器上下载下来,然后再返回给用户。此后(再次在这个位置的)用户访问时, 就会直接从 CDN 上缓存的文件下载,速度大大提升。 访问你网站的用户越多,这个速度提升就越明显。如果大多数的请求都没有缓存,那么几乎就没有什么速度提升。除此之外,最好将 CDN 的域名放在一个没有 Cookie 的根域名下。 关于 CDN 的推荐,已经在新的一篇文章里总结概括

国内 CDN 服务推荐

又拍云

又拍云是一个使用起来非常方便的 CDN 服务器,价格极低,按需付费。在国内 CDN 节点覆盖良好,并且还有实时统计等功能。同时支持绑定自定义域名,免费自定义 SSL 服务。 又拍云同时支持静态加速和动态加速两种,适合全站 CDN 加速。

国外 CDN 服务推荐

KeyCDN

KeyCDN 使用起来也非常方便,节点覆盖全球,价格极低,按需付费。它也有实时的日志。同时支持绑定自定义域名,免费自定义 SSL 服务,同时提供免费的 SSL 证书(Let’s Encrypt)。KeyCDN 只支持静态资源的加速,

CloudFlare

为了使用 CloudFlare,你需要更改你域名的 NS 解析提供商,仅此而已,无需其他设置。CloudFlare 默认是动态资源加速。同时提供免费的 SSL 证书(Comodo Positive SSL Wildcard),而且 CloudFlare 是有免费版的。

❌
❌