Amazon CloudFront 部署小指南(二)- 进阶部署

Linux
Docker
0
0
#### **内容简介** 在这篇博客文章中,您将进一步了解 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 的功能,这些功能可以帮助您根据需求定义内容交付方式,提高服务性能及可用性。 以下我们将从配置和经典需求中,带您了解如何更好的使用 CloudFront 进行加速设置。 一. 构建测试动态源站 二. 源站设置 三. 路径匹配及缓存策略 四. 回源请求及响应头策略 五. 错误响应设置 六. 缓存失效 通过本指南,您将学会如何利用 CloudFront 进行更多的配置构建,以符合实际业务的需求。 在小指南一中的 S3 静态源站基础上,我们将构建了一个动静兼具的最小源站架构。 架构图: ![1.png](https://dev-media.amazoncloud.cn/e1fdcf43608a4940ad573d4eb48ac3ce_1.png "1.png") #### **构建测试动态源站及展示页面** 在小指南一中,我们已经基于 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?trk=cndc-detail。 具体 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 ``` <!--StartFragment--> 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 ``` <!--StartFragment--> 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 设置,此处以下图的设置进行举例说明: ![2.png](https://dev-media.amazoncloud.cn/b286d3377bfe42e986933f62d63827c7_2.png "2.png") 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 ![3.png](https://dev-media.amazoncloud.cn/14ff5975e77042f0bd9621d5a5d5ff28_3.png "3.png") 除了用户携带的请求头可作为缓存键值以外,CloudFront 还内置了诸多供用户使用的请求头,用于识别用户的 设备类型 / 地理位置 等,具体可参考 – 添加 CloudFront 请求标头(https\://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/adding-cloudfront-headers.html?trk=cndc-detail), 您可根据具体业务需求,结合该头部信息进行缓存内容的区分。 另外,当服务中启用了压缩支持(compression support)时,CloudFront 还将根据不同的压缩格式分开进行缓存,并根据请求端发送的 accept-encoding 头部进行相应的内容返回: ![4.png](https://dev-media.amazoncloud.cn/2150fa7a2c064569a186b02638675fb9_4.png "4.png") 关于缓存键值的设置,为了保证实际使用 CloudFront 时维持一个良好且健康的缓存命中率,我们需要遵循“**非必要不添加缓存键值**”的原则,以下为一个常用的缓存键值场景举例: 页面中的某个静态元素,需要根据用户所携带的 v 参数,来作为缓存版本号识别,进行缓存区分,针对这种需求,我们可以这么设置缓存键值: ![5.png](https://dev-media.amazoncloud.cn/4cee3b9c9b614387baa138fd3e8fb211_5.png "5.png") 结合上述的原理以及我们准备好的源站环境,以下两个例子将解释网站中常用的两种场景—— **场景 1** : 网站中以 webp 结尾的路径需要缓存,且需要根据参数v进行缓存版本区分,缓存时间强制设置为 86400 根据场景需求我们可以进行以下设置: 路径匹配: ![6.png](https://dev-media.amazoncloud.cn/c89613473279457d87edf3f07875764f_6.png "6.png") 缓存 TTL 以及缓存键值设置,我们可以在 Policies – Cache 中,或是 Edit Behavior 页面中自定义构建缓存方式: ![7.png](https://dev-media.amazoncloud.cn/93f009f5fbd0422a9f8e93a939fabd8a_7.png "7.png") 缓存 TTL 及缓存键值设置,设置完毕后保存: ![8.png](https://dev-media.amazoncloud.cn/d5ce87aff25e413792226cca53a4274f_8.png "8.png") 选中刚才创建的 Cache Policy 并保存: ![9.png](https://dev-media.amazoncloud.cn/787b7d5fd100446a866f81446c348db0_9.png "9.png") **场景 2** :网站中的/api 路径,回源 EC2,且不缓存 在小指南一的基础上,我们的设置已经有了 S3 的源站,我们先创建 EC2 源,选中刚才创建的 EC2: ![9999.png](https://dev-media.amazoncloud.cn/fa0633706e3f4413ab12a0e996556dfd_9999.png "9999.png") 注:在此实验中,EC2 echoserver 监听的端口为 1028,您在创建 EC2 源时需注意指定端口,启用 HTTP/HTTPS,HTTPS 443 端口保持不变,为接下来的实验做准备。 我们可以设置以下的路径匹配,缓存策略则可以使用 CloudFront 托管的缓存策略 – Managed-CachingDisabled,具体设置如下: ![10.png](https://dev-media.amazoncloud.cn/31318e9f6389493e966afeb9529ee3b9_10.png "10.png") 同理,我们也将 index.html 按照 S3 为源站 / CachingDisable 的方式进行设置。 ![11.png](https://dev-media.amazoncloud.cn/7480bc46b9d6411186d76bf370a29a13_11.png "11.png") 效果测试: 在测试实际效果中,我们可以利用到 CloudFront 原生的 X-Cache 响应头,来浏览器中观察缓存状态是否符合预期。 使用 HTTP 方法访问您的 index.html 页面(如 http\://xxx.xxx.com/index.html), 在重复刷新页面后,可以看到 infra.png 此请求的 X-Cache 状态为Hit。 ![12.png](https://dev-media.amazoncloud.cn/a2e3a1452f23447abe8bffc9b6b1e71d_12.png "12.png") 而/api 路径由于缓存策略设置为不缓存,多次刷新后状态仍然为 Miss。 ![13.png](https://dev-media.amazoncloud.cn/57333139a639483c8af0b3658f24e934_13.png "13.png") #### **源组设置** 尽管有许多不同的方法可以提高网站的可用性,例如如果承载网站的原始服务器在亚马逊云中,则使用弹性负载平衡和多可用区,但 CloudFront 可为您的网站带来了更高的可用性。 网站可用性最常受到网络故障/服务器中断或内容不可用的影响,但有许多因素可能会影响网站的可用性。例如,网站停机可能是由于意外的硬件故障造成的。您可以通过使所有组件完全冗余来减轻这种类型的风险。在 CloudFront 的源设置中,提供了源组(Origin Group)的功能,您可以为源服务器端点提供多个冗余,避免由于一个源站故障或内容不可用而引起业务中断。 ![14.png](https://dev-media.amazoncloud.cn/e8e042fe14d049a0a935e43d4f25a1d5_14.png "14.png") 注:如果您使用的源站为非 Amazon 资源,如其他云服务计算资源,建议您在设置源站时启用源护盾(Origin Shield)功能,充分利用骨干网络,以保持业务的最佳性能以及可用性。 如以上截图,您在实际配置时,如需设置源组,则需要先设置出至少 2 个及以上的源,方可进行源组的设置,且您可灵活的指定源之间的主备关系,且根据源所响应的状态码,对满足特定状态码的请求进行自动宕切(Failover)。 以下我们举个例子,当访问的对象在 S3 上不存在时,CF 自动 Failover 到备用源站 EC2 去取内容: ![15.png](https://dev-media.amazoncloud.cn/167fa333f0d24499ad951ac54f524b7a_15.png "15.png") 创建完 Origin Group 后,在 Behavior 中设置一个测试用的行为,并将上述创建的源组应用到该行为中: ![16.png](https://dev-media.amazoncloud.cn/444e347491c242c4a007e0bf445cf9bc_16.png "16.png") 浏览器测试效果: \*由于 EC2 只启用了 HTTP,请使用 HTTP 访问测试,而非 HTTPS。 ![17.png](https://dev-media.amazoncloud.cn/4f2784c11d3045f5b0206eb03941f1a5_17.png "17.png") 我们可以看到当访问不存在的内容时,页面显示的不是主源上 S3 的报错信息,而是可以自动由备源 EC2 拿到内容,证明设置成功。 #### **回源请求及响应头策略** 在使用 CloudFront 为页面业务进行加速时,您同样可以决定回源时,CloudFront 应携带哪些必要信息回源,以及响应时在 CloudFront 设置相应的响应头策略,和缓存策略类似,您可以在 CloudFront 源请求策略(Origin Request Policy)中指定需要携带回源的请求头 / 参数 / Cookie,同时,您也可以灵活的制定响应头的策略,对指定的响应头进行增删改的操作,为了更好的理解,以下为一个应用案例—— 因业务需求,我们需要在 CloudFront 上实现以下三个策略: * 源站部署并监听了多个 Hostname,CloudFront 需携带用户请求的 Host 头供源站进行区分; * 业务方需要 CloudFront 携带用户的国家信息回源,供业务方进行信息收集并统计; * 在响应头中自定义响应头 x-cdn: CloudFront。 根据上述需求,您可以进行以下的相关设置: * 设置源请求策略携带 Host 和 CloudFront 内置的地理位置信息头 ![18.png](https://dev-media.amazoncloud.cn/d8826443e72f436fbff273b17bbece83_18.png "18.png") * 自定义设置响应头策略 ![19.png](https://dev-media.amazoncloud.cn/5eb987f622e64423b0fecc9c6b7f6409_19.png "19.png") 创建完毕后在行为路径“**/api**”中进行应用并部署: ![20.png](https://dev-media.amazoncloud.cn/070c9ae565e14e74a1c3a2fb32013f30_20.png "20.png") 效果测试: 利用到实验环境中的 echo server 响应内容为用户请求头的特性,我们可以很好的观察到配置的效果。 在部署上述请求头和响应头逻辑之前,我们可以看到该请求请求头携带回源的 Host 为 EC2 域名,响应头不携带 CORS 信息: ![21.png](https://dev-media.amazoncloud.cn/5ba50c37ece94c25a1c44ed7b07d0a04_21.png "21.png") 部署完逻辑后进行对比,我们可以看到用户请求的 host 信息已成功被携带回源,并且请求头中已携带了用户地理位置信息,响应头中也具备了我们自定义的响应头信息: ![22.png](https://dev-media.amazoncloud.cn/bef659aec04e4cf481cc7a8da1f46619_22.png "22.png") \*在上面的测试结果我们可以看到一个有意思的现象,即 UA 为 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail),这是因为在制定 Origin Policy 时,我们并未指定携带 UA 回源,在实际应用中,源服务往往需要根据请求头获取更多用户的请求特征,您可根据您的需要制定 CloudFront 应该携带哪些请求元素回源。 #### **定制错误响应** 在使用 CloudFront 进行内容分发时,我们可能会遇到 文件不存在 / 源服务器维护 / 源服务超时 等情况,导致客户端拿到错误响应或是源服务收到过多的错误请求,为了更好的缓解这种情况,CloudFront 可自定义错误响应码的缓存时间以及响应内容,以缓解源站持续收到触发错误响应码的请求,以及更友好的用户错误页面。 在这我们举例个场景,业务方需要针对源服务响应的 502 响应码进行 10 秒缓存,并且响应自定义的报错页面,我们可进行以下设置,来实现上述需求: 创建一个 custom error response ![23.png](https://dev-media.amazoncloud.cn/14a4c6bf530b43308f374ba2b12d75f4_23.png "23.png") 进行如下设置,指定 502 的 10 秒缓存时间,并且设置 sorry page 的路径,并进行 200 响应。 ![24.png](https://dev-media.amazoncloud.cn/e95b12cf0cfd4d578a994213b3928f78_24.png "24.png") 这边提供了一段简单的 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 源站中作为错误页面进行展示: ![25.png](https://dev-media.amazoncloud.cn/2be332b1af1c4a4ab02c77c18c560480_25.png "25.png") 上述操作完毕后,我们可以开始测试效果,由于部署 EC2 时,我们未开启 443 端口以及部署 HTTPS 证书,此时如果使用 HTTPS 访问 CloudFront,当 CloudFront 尝试用 HTTPS 回源 EC2 时,请求将会超时并产生 502 错误。 利用这个机制我们可以模拟源服务 502 的情况,使用 HTTPS 进行对 index.html 访问,未部署定制化错误响应前,我们可以看到以下效果: ![26.png](https://dev-media.amazoncloud.cn/8d7e79f2d0fd4aed8cda3e344fc729cd_26.png "26.png") 部署定制化错误响应后: ![27.png](https://dev-media.amazoncloud.cn/0c4c0dbccdf847bba9e97720880c0a1b_27.png "27.png") #### **缓存失效** 在实际业务中,您可能会遇到某些场景需要进行资源变更同时需要进行缓存失效,在 CloudFront Distribution 配置界面,您可以找到缓存失效的入口并进行缓存失效的动作,在确保源资源变更后,您方可在 CloudFront 上进行缓存失效的动作。 ![28.png](https://dev-media.amazoncloud.cn/747b110b1bb645949b9cdf48c3c9f65e_28.png "28.png") 接下来,我们使用构建好的环境来进行缓存刷新的测试,访问/index.html,直至静态内容呈现 Hit 状态,如下图所示: ![29.png](https://dev-media.amazoncloud.cn/e5ee3f1537b54d078fbd27fb71ace75b_29.png "29.png") 下一步,在 CloudFront 失效界面,添加需要失效缓存的 URL path: ![30.png](https://dev-media.amazoncloud.cn/96327977a5ba43e5964f78acc880326b_30.png "30.png") ![31.png](https://dev-media.amazoncloud.cn/2ccdc373e19a46dbb700aac35e75c12a_31.png "31.png") 提交并确认失效完成后,再次访问/index.html 页面,即可看到失效动作完成,再次访问缓存状态为 Miss。 ![32.png](https://dev-media.amazoncloud.cn/4735650c2efb4c04815c235349071dc7_32.png "32.png") #### **总结** 在此篇小指南中,我们了解到了如何进一步使用 CloudFront 实现更多灵活的设置,包括 定制缓存策略 / 设置源服务主备逻辑 / 针对回源请求进行制定 / 修改业务所需的响应头以及如果定制错误响应,根据本篇的指引,您可根据业务需求灵活构建 CloudFront 的行为以及如果响应客户请求。 #### 亚马逊云科技  ##### **CloudFront 部署小指南系列文章** [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南 (二)- 进阶部署: https\://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-two/?trk=cndc-detail [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南 (三)- 持续部署: https\://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-three/?trk=cndc-detail [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(四)- CloudFront Function 基础与诊断:https\://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-four/?trk=cndc-detail [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布:https\://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-five/?trk=cndc-detail [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(六)- Lambda\@Edge 基础与诊断:https\://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/?trk=cndc-detail #### **本篇作者** ![34.jpg](https://dev-media.amazoncloud.cn/b43cb85f7f5e474486dbf563feb799f8_34.jpg "34.jpg") **王骏兴** *亚马逊云科技边缘产品架构师,负责亚马逊云科技 Edge 服务领域在中国的技术推广。在 CDN 内容分发以及 WAF 领域拥有多年实战经验,专注于边缘服务设计以及体验优化。* ![35.jpg](https://dev-media.amazoncloud.cn/79fa9956c6fe4eed899a136c63abdcfe_35.jpg "35.jpg") **\ 崔俊杰** *亚马逊云科技高级产品解决方案架构师,负责亚马逊云科技云边缘安全相关的服务产品。为亚马逊云用户提供 DDoS 防御/网站前端安全防御/域名安全相关的产品咨询。对 Cloudfront,Shield,WAF,Route53,Global Accelerator 等云边缘安全相关产品有深入了解。在计算机安全、数据中心和网络领域有多年的工作经验。*
0
目录
关闭