本文结合自己工作的一个场景来简单的介绍下怎么使用AWS CloudFront 加速&聚合多个源站。
具体的场景如下,客户原先有多个网站站但是他们的域名不统一,而且这些网站CDN的加速现状也不一致(有的加了CDN有的没有加CDN或者使用了多家CDN厂商的产品)。客户希望有一种CDN解决方案做到如下的2个场景:
- SEO场景,通过一个统一的域名集中暴露出前面的多个不同域名的内容
- CDN统一管理,由多个CDN供应商迁移到一家CDN供应商来方便统一管理并且为不同的源设置不同的缓存策略。
我们假设客户先有如下的多个源站
源站名称 | 域名 | 缓存策略 | |
---|---|---|---|
自建Blog站,使用wordpress系统自建在Linux上 | blog-a-company.com | 缓存任意请求,其中post请求不缓存 | |
自建官网| | a-company.com | 缓存静态资源(js/css/image)不缓存动态HTTP RESTFul API | |
电商网站(shopify托管) | a-company.myshopify.com | 不缓存 |
现在需要方便SEO,只让用户能通过a-company.com来集中访问。
这个需求的实现有如下的技术前提:
- 首先AWS CloudFront看到的全部的来访域名都统一是a-company.com
- AWS CloudFront只能通过path来决定回源到具体的那个源,目前不支持按照其他的参数进行回源目标的判断。
方案实现
有2种方案来实现
方案一:按照路径进行回源
首先是讲上述的3个站添加为源站,然后按照路径来进行回源。比如当用户访问a-company.com
时先看访问的URL path
,如果是/office-wesite
那么回源到自建的官网a-company.com
,如果是/blog
那么回源到自建的blog系统blog-a-company.com
,最后默认回源到a-company.myshopify.com
。
在具体的实现上我们可以这样设置CloudFront,首先时设置好如上3个源站 然后是为不同的源站按照path匹配不同的回源规则,这里我们除了可以设置基本的按照path规则回到具体的源外,还可以对某个回源的具体动作做精细的差异化管理。比如缓存策略、回源的HTTP/HTTPS协议策略、回源时的源请求策略等。这样可以满足我们的不同源内容的缓存需求。
这个方案也有一定的固有的局限性,具体在:
- 由于AWS CloudFront只能通过path来决定回源到具体的那个源,那么我们只能按照path来决定回到哪个源,不能按照请求参数,header,body等其他请求变量来进行动态回源。
- 各个源站必须互相协调好路径,它们的可访问path不能冲突或者重合,一般这个需要自建的源站在路径设计上做好适配,否则会有混乱。
关于AWS Cloudfornt源站设置和回源设置请看
- Path pattern
- Working with distributions
- Working with policies
- Configuring secure access and restricting access to content
- Request and response behavior
方案二:使用lambda@edge动态动态回源
使用Cloudfront自带的边缘计算功能,当有回源请求时,我们通过在Cloudfront的边缘节点运行Nodejs/Python3脚本来实现具体的回源逻辑动态化。这是我们可以实现方案一无法实现的按照请求参数,header,body等其他请求变量来进行动态回源的功能。
关于cloudfront的边缘计算详情请看Customizing at the edge with functions
具体的架构如下: 当cloudfront需要回源的时候,我们通过处理couldfront的Origin request
事件带过来的详细的请求参数来完成动态回源。
这个方案相比方案一有明显的灵活性优势。由于Cloudfront有双级缓存(),回源的次数远少于实际的用户访问次数,额外引入的边缘计算成本很低。
关于Shopify做源站的思考
Shopify其实本身有自己的CDN服务,其全部的资源都经过了Cloudflare的CDN加速而且不能自己调整,其实额外再加一层缓存的意义不是很大,除了有少量的地区覆盖更好的扩展外。但是结合SEO和品牌资源的集中管理角度,用额外的CDN也有现实意义。
加速Shopify遇到的问题
指向Shopify的域名有3种域名类型,分别为primary,alias,redirect。不同的类型的作用不一样,详情请看Changing the domain type and target
如果我们不结合primary,alias这2种域名类型的话,为shopify添加额外的CDN会产生问题。比如我有一个primary shopify站(a-company.myshopify.com),我想换用全新的品牌站(a-company.com)包装primary shopify站(a-company.myshopify.com)。那么当你访问额外的CDN加速后的a-company.com时进行某些操作(比如登陆或者访问商品)依然会跳转为a-company.myshopify.com。这样会让用户产生迷惑和安全担忧,因为浏览器地址栏发生了域名级别的变化。
一般的解决方式是:
- 新建一个二级域名
shop.a-company.com
绑定(以CNAME的方式)在shopify上 - 将
a-company.com
绑定(以CNAME的方式)在shopify上 - 设置
a-company.com
为alias,将shop.a-company.com
设置为primary。alias指向primary - 设置Cloudfront,将priamry添加为源站(shop.a-company.com),以后回源就用primary站
- 修改alias的CNAME指向Couldfront的
Distribution domain name
域名- 修改alias的CNAME后,shopify会告警但是完全没有影响
- 继续按照Cloudfront的标准回源规则进行设置和验证即可
最后的整体实现如下: