亚马逊AWS官方博客
Amazon CloudFront 部署小指南(二)- 进阶部署
内容简介
在这篇博客文章中,您将进一步了解 Amazon CloudFront 的功能,这些功能可以帮助您根据需求定义内容交付方式,提高服务性能及可用性。
以下我们将从配置和经典需求中,带您了解如何更好的使用 CloudFront 进行加速设置。
一. 构建测试动态源站
二. 源站设置
三. 路径匹配及缓存策略
四. 回源请求及响应头策略
五. 错误响应设置
六. 缓存失效
通过本指南,您将学会如何利用 CloudFront 进行更多的配置构建,以符合实际业务的需求。
在小指南一中的 S3 静态源站基础上,我们将构建了一个动静兼具的最小源站架构。
架构图:
构建测试动态源站及展示页面
在小指南一中,我们已经基于 S3 构建了一个最小架构的静态源站,为了更好的配合以下设置,接下来我们需要构建一个响应动态内容的源站,为了方便演示,此处以一个 echo-server 的 Docker 镜像,创建一个 httpecho 的容器让它能够把我们通过 http 访问服务器的请求头都提取出来作为 http 响应给我们的浏览器。
首先启用一个 t2.micro 的 EC2,使用 Amazon Linux2 AMI 启动。
在此 EC2 上安装 Docker,参考 https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/docker-basics.html。
具体 Linux 命令如下:
- 安装 docker
- 赋予 ec2-user 用户 docker 启动的 linux 权限
- 退出当前 ssh session 以使权限生效
- 使用 ec2-user 再次 login 检查 docker 信息
输出如下即为 docker 安装成功:
- 运行 echo-server docker image,监听 TCP 1028 端口
- curl 检查本地服务
输出如下即表示服务正常。该输出表示 echo-server 服务器收到 curl 送来的 http 请求,内容非常简单:
接下来,为了更便于展示效果,我们将使用一个简单的 HTML 页面,将静态元素和动态元素进行结合,您可以先将以下 html 代码保存为 index.html 的并上传至 S3 当中:
路径匹配及缓存策略
配置缓存策略之前,我们需要先了解下 CloudFront 如何根据行为(Behavior)中的路径识别,来找到对应的策略,配置路径匹配(Path Pattern)时,我们需要遵循以下的规则:
- 按序执行,规则序号越小,优先级越高
- * 匹配 0 个或多个字符
- 大小写敏感
- ?匹配 1 个字符
- 不支持正则表达式
同时,为了让缓存结果符合预期,我们也需要了解缓存策略(Cache Policy)中的 TTL 设置以及缓存键值(Cache Key)设置的工作方式:
关于 TTL 设置,此处以下图的设置进行举例说明:
CloudFront 将根据源服务器响应的 cache-control 或 expire,结合缓存策略中的 TTL 设置决定缓存多长时间,此处举三个例子来说明最终的效果:
- 源站响应了 Cache-Control: max-age=3600,由于 3600 落在了 TTL 最大值和最小值 1 – 86400 的区间,则 CloudFront 将缓存 3600 秒
- 源站响应了 Cache-Control: max-age=99999,由于 99999 超出了 TTL 最大值 86400,则 CloudFront 将缓存 86400 秒
- 源站未响应 cache-control或expire,由于默认 TTL(Default TTL)设置为 60 秒,则 CloudFront 将缓存 60 秒
关于缓存键值的设置,CloudFront 可识别以下三种请求元素,进而将指定元素作为缓存键值进行缓存,分别为:请求头 / 参数 / Cookie
除了用户携带的请求头可作为缓存键值以外,CloudFront 还内置了诸多供用户使用的请求头,用于识别用户的 设备类型 / 地理位置 等,具体可参考 – 添加 CloudFront 请求标头,您可根据具体业务需求,结合该头部信息进行缓存内容的区分。
另外,当服务中启用了压缩支持(compression support)时,CloudFront 还将根据不同的压缩格式分开进行缓存,并根据请求端发送的 accept-encoding 头部进行相应的内容返回:
关于缓存键值的设置,为了保证实际使用 CloudFront 时维持一个良好且健康的缓存命中率,我们需要遵循“非必要不添加缓存键值”的原则,以下为一个常用的缓存键值场景举例:
页面中的某个静态元素,需要根据用户所携带的 v 参数,来作为缓存版本号识别,进行缓存区分,针对这种需求,我们可以这么设置缓存键值:
结合上述的原理以及我们准备好的源站环境,以下两个例子将解释网站中常用的两种场景——
场景 1: 网站中以 webp 结尾的路径需要缓存,且需要根据参数v进行缓存版本区分,缓存时间强制设置为 86400
根据场景需求我们可以进行以下设置:
路径匹配:
缓存 TTL 以及缓存键值设置,我们可以在 Policies – Cache 中,或是 Edit Behavior 页面中自定义构建缓存方式:
缓存 TTL 及缓存键值设置,设置完毕后保存:
选中刚才创建的 Cache Policy 并保存:
场景 2:网站中的/api 路径,回源 EC2,且不缓存
在小指南一的基础上,我们的设置已经有了 S3 的源站,我们先创建 EC2 源,选中刚才创建的 EC2:
注:在此实验中,EC2 echoserver 监听的端口为 1028,您在创建 EC2 源时需注意指定端口,启用 HTTP/HTTPS,HTTPS 443 端口保持不变,为接下来的实验做准备。
我们可以设置以下的路径匹配,缓存策略则可以使用 CloudFront 托管的缓存策略 – Managed-CachingDisabled,具体设置如下:
同理,我们也将 index.html 按照 S3 为源站 / CachingDisable 的方式进行设置。
效果测试:
在测试实际效果中,我们可以利用到 CloudFront 原生的 X-Cache 响应头,来浏览器中观察缓存状态是否符合预期。
使用 HTTP 方法访问您的 index.html 页面(如 http://xxx.xxx.com/index.html),在重复刷新页面后,可以看到 infra.png 此请求的 X-Cache 状态为Hit。
而/api 路径由于缓存策略设置为不缓存,多次刷新后状态仍然为 Miss。
源组设置
尽管有许多不同的方法可以提高网站的可用性,例如如果承载网站的原始服务器在 AWS 云中,则使用弹性负载平衡和多可用区,但 CloudFront 可为您的网站带来了更高的可用性。
网站可用性最常受到网络故障/服务器中断或内容不可用的影响,但有许多因素可能会影响网站的可用性。例如,网站停机可能是由于意外的硬件故障造成的。您可以通过使所有组件完全冗余来减轻这种类型的风险。在 CloudFront 的源设置中,提供了源组(Origin Group)的功能,您可以为源服务器端点提供多个冗余,避免由于一个源站故障或内容不可用而引起业务中断。
注:如果您使用的源站为非 Amazon 资源,如其他云服务计算资源,建议您在设置源站时启用源护盾(Origin Shield)功能,充分利用骨干网络,以保持业务的最佳性能以及可用性。
如以上截图,您在实际配置时,如需设置源组,则需要先设置出至少 2 个及以上的源,方可进行源组的设置,且您可灵活的指定源之间的主备关系,且根据源所响应的状态码,对满足特定状态码的请求进行自动宕切(Failover)。
以下我们举个例子,当访问的对象在 S3 上不存在时,CF 自动 Failover 到备用源站 EC2 去取内容:
创建完 Origin Group 后,在 Behavior 中设置一个测试用的行为,并将上述创建的源组应用到该行为中:
浏览器测试效果:
*由于 EC2 只启用了 HTTP,请使用 HTTP 访问测试,而非 HTTPS。
我们可以看到当访问不存在的内容时,页面显示的不是主源上 S3 的报错信息,而是可以自动由备源 EC2 拿到内容,证明设置成功。
回源请求及响应头策略
在使用 CloudFront 为页面业务进行加速时,您同样可以决定回源时,CloudFront 应携带哪些必要信息回源,以及响应时在 CloudFront 设置相应的响应头策略,和缓存策略类似,您可以在 CloudFront 源请求策略(Origin Request Policy)中指定需要携带回源的请求头 / 参数 / Cookie,同时,您也可以灵活的制定响应头的策略,对指定的响应头进行增删改的操作,为了更好的理解,以下为一个应用案例——
因业务需求,我们需要在 CloudFront 上实现以下三个策略:
- 源站部署并监听了多个 Hostname,CloudFront 需携带用户请求的 Host 头供源站进行区分;
- 业务方需要 CloudFront 携带用户的国家信息回源,供业务方进行信息收集并统计;
- 在响应头中自定义响应头 x-cdn: CloudFront。
根据上述需求,您可以进行以下的相关设置:
- 设置源请求策略携带 Host 和 CloudFront 内置的地理位置信息头
- 自定义设置响应头策略
创建完毕后在行为路径“/api”中进行应用并部署:
效果测试:
利用到实验环境中的 echo server 响应内容为用户请求头的特性,我们可以很好的观察到配置的效果。
在部署上述 请求头和响应头逻辑之前,我们可以看到该请求请求头携带回源的 Host 为 EC2 域名,响应头不携带 CORS 信息:
部署完逻辑后进行对比,我们可以看到用户请求的 host 信息已成功被携带回源,并且请求头中已携带了用户地理位置信息,响应头中也具备了我们自定义的响应头信息:
*在上面的测试结果我们可以看到一个有意思的现象,即 UA 为 Amazon CloudFront,这是因为在制定 Origin Policy 时,我们并未指定携带 UA 回源,在实际应用中,源服务往往需要根据请求头获取更多用户的请求特征,您可根据您的需要制定 CloudFront 应该携带哪些请求元素回源。
定制错误响应
在使用 CloudFront 进行内容分发时,我们可能会遇到 文件不存在 / 源服务器维护 / 源服务超时 等情况,导致客户端拿到错误响应或是源服务收到过多的错误请求,为了更好的缓解这种情况,CloudFront 可自定义错误响应码的缓存时间以及响应内容,以缓解源站持续收到触发错误响应码的请求,以及更友好的用户错误页面。
在这我们举例个场景,业务方需要针对源服务响应的 502 响应码进行 10 秒缓存,并且响应自定义的报错页面,我们可进行以下设置,来实现上述需求:
创建一个 custom error response
进行如下设置,指定 502 的 10 秒缓存时间,并且设置 sorry page 的路径,并进行 200 响应。
这边提供了一段简单的 html 文本页面:
我们将该 html 上传至 S3 源站中作为错误页面进行展示:
上述操作完毕后,我们可以开始测试效果,由于部署 EC2 时,我们未开启 443 端口以及部署 HTTPS 证书,此时如果使用 HTTPS 访问 CloudFront,当 CloudFront 尝试用 HTTPS 回源 EC2 时,请求将会超时并产生 502 错误。
利用这个机制我们可以模拟源服务 502 的情况,使用 HTTPS 进行对 index.html 访问,未部署定制化错误响应前,我们可以看到以下效果:
部署定制化错误响应后:
缓存失效
在实际业务中,您可能会遇到某些场景需要进行资源变更同时需要进行缓存失效,在 CloudFront Distribution 配置界面,您可以找到缓存失效的入口并进行缓存失效的动作,在确保源资源变更后,您方可在 CloudFront 上进行缓存失效的动作。
接下来,我们使用构建好的环境来进行缓存刷新的测试,访问/index.html,直至静态内容呈现 Hit 状态,如下图所示:
下一步,在 CloudFront 失效界面,添加需要失效缓存的 URL path:
提交并确认失效完成后,再次访问/index.html 页面,即可看到失效动作完成,再次访问缓存状态为 Miss。
总结
在此篇小指南中,我们了解到了如何进一步使用 CloudFront 实现更多灵活的设置,包括 定制缓存策略 / 设置源服务主备逻辑 / 针对回源请求进行制定 / 修改业务所需的响应头以及如果定制错误响应,根据本篇的指引,您可根据业务需求灵活构建 CloudFront 的行为以及如果响应客户请求。