如何在AWS 中实现动态CDN

CDN 不是一个新名词,这个把缓存分布到世界各地的技术起码出现了 10 年。最近又火起来,原因是用户对网络响应时间的要求深化。国内就有阿里云的 CDN, ChinaCache, Baidu+Cloudfare, UCloud, 7牛 还有很多。。。因为网络问题,很多大公司都会采用国外服务器,然后把内容通过CDN 推到国内。

技术上,我认为这么多公司一起做CDN,其中一个原因就是这东西不复杂,当然国内国外的支持还会加上一些其他问题。主流技术就是 Nginx / Varnish 作为 File Cache, 然后部署 全局负载均衡GSLB(上一篇文章也有提及过)。 以技术角度来看,我是不会自己架一个CDN网络的,因为你必须有上百节点的才算得上CDN,个人架设成本有点高。

选择 CDN 时一半会考虑以下的因素:

支持 Cache invalidation

Invalidation 所需要的时间与价格

流量费不要超过 USD 0.14/GB

支持动态 CDN

支持子域名 (CloudFlare / 安全宝 都需要域名切换,防DDOS)

支持 Cache Behaviour (不同的路径有不同的 cache 特性)

可以 pass through header / cookie

Respect Cache-control header

最好可以直接有操作介面更改 header

支持 edge side include

相信能做到以上的,就不纯粹是个简单的CDN,是个真正的CDN。今天主要分享的是第 4)点 动态 CDN

AWS 在 2013 年开始在 Cloudfront 支持动态CDN,意思就是可以把 html 也存到 CDN 上,用户拿到 HTML 和 静态文件都在 CDN 上,不需要向服务器 (origin) 请求。原理上,这就支持无限的访问。read 请求日千万不是问题,问题你的信用卡能刷多少钱而已。
如何在AWS 中实现动态CDN

这个 Dynamic CDN 的原理是这样的 比如,以 abc.com为例子作一下说明。

  1. abc.com CNAME 去 Cloudfront 的域名 (xxxxxxxx.aws.cloudfront.com)

  2. 在 xxxxxxxx.aws.cloudfront.com 以下的 Cloudfront ID (cloudfrontID.default.cloudfront.com) 接受 abc.com 的请求

  3. xxxxxxxx.aws.cloudfront.com 指向 origin.abc.com 拿数据 (就是本服务器)

  4. 要是请求没有 cloudfront 本地 cache, 就继续,否则反回 cache

  5. 要是请求不是特定的 path ( cache behaviour),则反回

  6. cloudfrontID.default.cloudfront.com 向 web 服务器 (Origin) 请求 object

    (html / css / .jpg / …)
  7. 把 header (cache-header / CORs) 也记到 cache 中

  8. 把 xxx.default.cloudfront.com 的 cache 反回到 abc.com 的客户端

  9. 跟据在第 7) 点 定义的 header按时间清理缓存

  10. 跟据请求的来源IP,在世界各地每一个edge 上操作 1-9

这有点像反向代理,比如 Varnish 就在做差不多的事。只是CDN 在用 edge cache. Varnish 一般的使用情况是把文件缓存最长时间,然后根据 Origin 给的指令来更新缓存。这是客户最想要的,这样就不会有 “第一位用户变慢” 这样的问题。但要是用过好几个 CDN 的人就会发现,市面上没有CDN 支持永久缓存这回事。原因在哪?这没有官方回应,我感觉是 edge cache 是很多很多的服务器,在 AWS 上跑一次 cache invalidation 去清理所有 edge 上的 cache 要花上 20-30 分钟,要是每一次的 object 更新也得像 Varnish 去 “push” 更新,就会花上很大的成本。倒不如自动 Expire, 然后在下一位用户有需要时,才把最近那地理位置的 edge cache 上加一个 object cache. 这样就省去一笔很大的成本。

好的 CDN 得支持 Behavior, 就是路径不同的特性,在不同的应用上,特别是已登录的用户,使用太多的 cache 会令系统出问题。得跟据路径来删除/加速 刷新。
如何在AWS 中实现动态CDN

要是支持登录用户的话, Cookie 要用客户端直接传送到 Origin, 所以得支持 (forward cookie)
如何在AWS 中实现动态CDN

每个 CDN 会有一个 Default behaviour, 就是不指定情况下,都跟据这个 behaviour 作出回应。比如我们要支持用户登录,得把 session 通过 Dynamic CDN 回传到 origin
如何在AWS 中实现动态CDN

整体来说,AWS Cloudfront 是个很不错的 CDN, 需要有的都有了。要是能支持 ESI (Edge Side Includes) 就更好了。市面上的云加速 / 云防护大约都是 Dynamic CDN 的原理,至于能加速多少,能不能支持用户登录,还有 Cookie/Cache-header 等问题,就是深度用户需要关注的地方。

下次我们可以讨论如何在全局负载均衡GSLB 加上 Cloudfront 做全球化布局的动态 CDN。

相关推荐