Amazon CloudFront 部署小指南(二)- 进阶部署
内容简介在这篇博客文章中,您将进一步了解 Amazon CloudFront 的功能,这些功能可以帮助您根据需求定义内容交付方式,提高服务性能及可用性。以下我们将从配置和经典需求中,带您了解如何更好的使用 CloudFront 进行加速设置。一. 构建测试动态源站二. 源站设置三. 路径匹配及缓存策略四. 回源请求及响应头策略五. 错误响应设置六. 缓存失效通过本指南,您将学会如何利用 Cloud
内容简介
在这篇博客文章中,您将进一步了解 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 命令如下:
1. 安装 docker
sudo yum update -y
sudo amazon-linux-extras install docker
左滑查看更多
2. 赋予 ec2-user 用户 docker 启动的 linux 权限
sudo usermod -a -G docker ec2-user
左滑查看更多
3. 退出当前 ssh session 以使权限生效
logout
4. 使用 ec2-user 再次 login 检查 docker 信息
sudo service docker start
docker info | grep Ver
输出如下即为 docker 安装成功:
Server Version: 20.10.7
Cgroup Version: 1
Kernel Version: 4.14.47-64.38.amzn2.x86_64
左滑查看更多
5. 运行 echo-server docker image,监听 TCP 1028 端口
docker run -d --name httpecho -p 1028:8080 jmalloc/echo-server httpecho
左滑查看更多
6. curl 检查本地服务
curl 127.0.0.1:1028
输出如下即表示服务正常。该输出表示 echo-server 服务器收到 curl 送来的 http 请求,内容非常简单:
Request served by 16e51706efbe
HTTP/1.1 GET /
Host: 127.0.0.1:1028
User-Agent: curl/7.79.1
Accept: /
左滑查看更多
接下来,为了更便于展示效果,我们将使用一个简单的 HTML 页面,将静态元素和动态元素进行结合,您可以先将以下 html 代码保存为 index.html 的并上传至 S3 当中:
<!DOCTYPE html>
<html lang="en">
<body>
<table border="1" width="600px" height="800px">
<thead>
<tr><td height="50px"><h1>CloudFront Lab</h1></td></tr>
</thead>
<tfoot>
<tr><td height="50px">AWS Edge Services - Demo</td></tr>
</tfoot>
<tbody>
<tr><td height="50px">Response sent by API</td></tr>
</tbody>
<tbody>
<tr><td height="300px"> <img src='../infra.png' style="width:100%; height:100%;"></img></td></tr>
</tbody>
<tbody>
<tr><td height="650px"> <iframe src='../api' style="width:100%; height:100%;"></iframe></td></tr>
</tbody>
</table>
</body>
</html>
左滑查看更多
路径匹配及缓存策略
配置缓存策略之前,我们需要先了解下 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 请求标头(https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html),您可根据具体业务需求,结合该头部信息进行缓存内容的区分。
另外,当服务中启用了压缩支持(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。
源组设置
尽管有许多不同的方法可以提高网站的可用性,例如如果承载网站的原始服务器在亚马逊云中,则使用弹性负载平衡和多可用区,但 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 文本页面:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to CloudFront!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Sorry, Your content is not available!</h1>
</body>
</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 的行为以及如果响应客户请求。
亚马逊云科技
CloudFront 部署小指南系列文章
Amazon CloudFront 部署小指南 (二)- 进阶部署:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-two/
Amazon CloudFront 部署小指南 (三)- 持续部署:
https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-three/
Amazon CloudFront 部署小指南(四)- CloudFront Function 基础与诊断:https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-four/
Amazon CloudFront 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布:https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-five/
Amazon CloudFront 部署小指南(六)- Lambda@Edge 基础与诊断:https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/
本篇作者
王骏兴
亚马逊云科技边缘产品架构师,负责亚马逊云科技 Edge 服务领域在中国的技术推广。在 CDN 内容分发以及 WAF 领域拥有多年实战经验,专注于边缘服务设计以及体验优化。
崔俊杰
亚马逊云科技高级产品解决方案架构师,负责亚马逊云科技云边缘安全相关的服务产品。为亚马逊云用户提供 DDoS 防御/网站前端安全防御/域名安全相关的产品咨询。对 Cloudfront,Shield,WAF,Route53,Global Accelerator 等云边缘安全相关产品有深入了解。在计算机安全、数据中心和网络领域有多年的工作经验。
听说,点完下面4个按钮
就不会碰到bug了!
更多推荐
所有评论(0)