亚马逊AWS官方博客

Amazon S3 + Amazon CloudFront: 云中的绝妙搭配

存储和加速内容,同时提高安全性并降低成本

快速并可扩展地存储和分发内容

如果您拥有一个网站、应用程序或其他 Web 资源,您可能会拥有静态内容。静态内容包括图像、视频或音乐等文件,甚至是 .css 或 js 等脚本。在云前时代,您需要将这些文件放入一个标准的服务器,然后通过 Internet 服务来自全球或某个特定地理位置的所有访问者。使用云服务后,出现了一种可以更快分发并且具有更好可扩展性的解决方案。此博文将介绍如何使用 Amazon Simple Storage Service (S3)Amazon CloudFront,从而可扩展地存储、保护和分发您的静态内容。我们使用了一个 CloudFormation 模板,它可以快速为您预置这些服务,从而让您只需几次点击即可开始使用。(我们将稍后演示其设置。)

第一步是以安全、可扩展的方式存储您的内容。将静态内容存储在 Amazon S3 存储桶中,是通过 Internet 分发静态内容的简单灵活方式。 S3 的设置和使用十分方便,专为存储和检索来自 Internet 上任何地方、任何数量的文件或对象而设计。它使用简单,以极低的成本提供持久、高度可用和可扩展的数据存储。

只要将内容放入云中的 S3 存储桶,许多事情将变得十分简单。首先,您不需要计划和配置特定数量的存储空间,因为 S3 存储桶会自动扩展。此外,由于 S3 属于无服务器服务,您不需要亲自管理存储文件的服务器或安装补丁;您只需放入和提取内容。最后,即使您需要为某个应用程序运行服务器(例如,由于您拥有一个动态应用程序),该服务器也可以较小,因为它不需要处理有关静态内容的请求。

使用 S3 来存储静态内容具有许多优势。但为了帮助优化应用程序的性能和安全性,同时有效地管理成本,我们建议您同时设置Amazon CloudFront,以结合 S3 存储桶来服务和保护内容。CloudFront 是一种内容分发网络 (CDN) 服务,以安全、可扩展的方式在全世界分发静态和动态 Web 内容、视频流和 API。与直接从 S3 向用户分发数据相比,通过 CloudFront 分发数据的设计具有更好的成本经济性。

CloudFront 通过全球性的数据中心网络来分发内容,这些数据中心被称为边缘站点。使用边缘服务器来缓存和服务内容,让内容更加靠近访问者,从而提高了性能。如以下地图所示,CloudFront 在全球各地建立了边缘服务器:

用户请求您使用 CloudFront 来服务的内容时,他们的请求将会被路由到附近的边缘站点。如果 CloudFront 拥有所请求文件的缓存副本,CloudFront 会将该副本交付给用户,从而实现快速(低延迟)响应。如果所请求的文件没有缓存,CloudFront 将会从您的源(例如存储您的内容的 S3 存储桶)检索该文件。然后,对于同一内容的下一个本地请求,由于它已经在附近的站点缓存,因此可以立即服务。

通过在边缘站点缓存内容,CloudFront 减少了 S3 存储桶的负载,帮助确保您在用户请求内容时更快响应。此外,使用 CloudFront 来分发内容数据往往要比直接从 S3 分发具有更高的成本经济性,同时从 S3 向 CloudFront 传输数据不会发生数据传输费。您只需为通过 Internet 从 CloudFront 传输的数据付费,此外还需支付请求费(请参阅完整的定价信息)。

即使您不希望缓存内容(例如,由于您服务的是动态内容),CloudFront 也可以改进内容的分发,因为边缘站点在靠近用户的地方建立和维持连接。CloudFront 还可利用 AWS 的全球私有网络,这是一个 Internet 上的独立骨干网络,可帮助避免全球联网问题,提供更好的静态和动态内容性能。

图形更能形象地说明它的工作原理,请参阅下图演示的场景。我们将内容存储在位于欧洲某个区域的 S3 存储桶中,来自全球各地的用户都可能访问该内容。如箭头所示,每当用户请求内容时,请求必须通过公有 Internet 到达源位置(位于欧洲的 S3 存储桶)。根据用户具体位置的不同,这可能花费很长的时间。延迟甚至可能导致一些用户请求被弹回,页面返回错误。

现在假设我们使用 S3 存储桶来设置 CloudFront。在下面的演示中,您可以看到将不再需要让请求遍历全球来获取我们的内容。相反,请求将路由至“延迟最低”的边缘站点;也就是在传输速度上距离最近的站点。然后如图中的绿色箭头所示,CloudFront 将直接向附近的请求用户快速分发缓存的内容。如果边缘服务器中还没有缓存该内容,则 CloudFront 会从 S3 存储桶源中检索。由于内容通过 AWS 私有网络传输,而不经过公有 Internet,并且 CloudFront 优化了 TCP 握手,请求和内容返回的速度仍然远远快于通过公有 Internet 访问。

保护内容安全

通过 Internet 分发内容的企业经常会希望限制对文档、商业数据、媒体流或其他内容的访问权限,从而仅限付费客户等选定的用户可以请求这些内容。通过使用 CloudFront,我们可以设置地理限制、签名 URL、签名 Cookie 等额外的访问限制,从而根据不同的条件进一步限制对内容的访问。

CloudFront 的另一个安全功能是源访问身份 (OAI),此功能会将 S3 存储桶及其内容限制为仅限 CloudFront 以及它所执行的操作可以访问。此博文中的 CloudFormation 模板包含了 OAI,以帮助确保您的内容得到保护和限制。

 

CloudFront 包含额外的保护功能,防止恶意利用漏洞。为提供这些保护,CloudFront 集成了 Web 应用程序防火墙 AWS WAF(它可帮助保护 Web 应用程序,防止常见的 Web 漏洞利用行为)以及 AWS Shield(适用于在 AWS 上运行的 Web 应用程序的托管 DDoS 防护服务)。AWS WAF 可让您按自己指定的条件控制对内容的访问,例如按 IP 地址或内容查询的查询字符串值。然后 CloudFront 会在满足条件时返回请求的内容,或返回一个 HTTP 403 状态代码(禁止访问)。所有 CloudFront 客户都可免费享受 AWS Shield Standard 提供的自动防护。如果客户希望获得更深入的见解,增强风险化解能力,以及面对 DDoS 攻击时的成本保护,则可以使用 AWS Shield Advanced

开始使用

为了尽量方便 S3 和 CloudFront 的设置,我们创建了两个 CloudFormation 模板以供您开始使用。第一个模板(模板 A)会创建一个全新的 S3 存储桶,然后一个 CloudFront 分配,并使用源访问身份 (OAI) 来限制为仅允许通过 CloudFront 通过访问存储桶。第二个模板(模板 B)会创建一个新的 CloudFront 分配,您可以将此它分配给您可能存储 Web 内容的现有 S3 存储桶,并且可以选择是否利用 OAI 来保护该内容的安全。

执行以下步骤来复制您自己环境中的设置:

1) 登录控制台,然后根据您的使用案例单击相关的“启动堆栈”按钮。这将会在您的 AWS 账户中启动一个 CloudFormation 堆栈。请注意此堆栈将在弗吉尼亚北部 (us-east-1) 区域启动。

堆栈 A — 启动新的 S3 存储桶和新的 CloudFront 分配

堆栈 B — 启动新的 CloudFront 分配并将它分配给某个现有的 S3 存储桶

 

2-A) 如果您选择堆栈 A,则按照向导的提示操作,然后在最后一步选择“创建”按钮。完成 CloudFormation 堆栈的创建通常需要大约 15 分钟。运行期间您可以简短休息一下,然后返回继续。

2-B) 如果您选择堆栈 B,则选择您是否希望对您的 S3 存储桶执行 OAI,然后键入您希望为其分配 CloudFront 分配的 S3 存储桶名称。您可以在 S3 控制台找到当前 S3 存储桶的名称。

3) CloudFormation 的状态变为 CREATE_COMPLETE 后,选择该堆栈,然后选择“Outputs”选项卡。记下此处列举的两个值:您的 S3 存储桶名称(例如 S3BucketName)和您的 CloudFront 域名 — 堆栈 A:CfDistributionDomainName;启用 OAI 的堆栈 B:CfDistributionDomainNameWithOAI;未启用 OAI 的堆栈 B:CfDistributionDomainName.。您将在稍后使用这些值来测试对文件的访问。

4) 打开 S3 控制台,然后将一个图片文件上传到 CloudFormation 创建的 S3 存储桶中。在此例中,我上传了一个名为 image.jpg 的文件。

5) 完成文件上传后,选择访问文件的 URL。如果您选择使用 OAI 功能,则存储桶中的文件不能直接 S3 公开访问,因此您将看到类似于如下屏幕截图的消息。

6) 键入 URL 以使用 CloudFront 分配的域名访问该文件。使用您在第 3 步复制的 CloudFront 分配值,然后添加您在第 4 步添加到 S3 存储桶的文件名称。在此例中,您可以看到我上传了一张我的狗的照片,名为 Java。由于 CloudFront 为该 S3 存储桶配置了 OAI 访问,您可以在使用 CloudFront URL 时查看该照片。

7) 最后,使用新的 CloudFront URL 更新引用此内容的任何代码和 Web 属性。

跟踪性能

我们使用 CloudFormation 模板创建了一个 S3 存储桶,然后添加 CloudFront 来访问 S3 存储桶中的内容。但添加 CloudFront 是否是值得的额外步骤? 下面我们来看从全球不同地方查看图片时的性能提升程度。为此,我将使用一个在线平台来衡量不同地理位置加载网站和内容的时间。

我的 S3 存储桶源位于弗吉尼亚北部区域。为比较使用和不使用 CloudFront 时的性能差异,我在同一区域创建了一个含有相同图片文件但未添加 CloudFront 的 S3 存储桶。如下面的几张图所示,我从三个位置进行了加载时间测试:瑞典斯德哥尔摩、美国纽约和澳大利亚墨尔本。

在每个位置,我进行了四次试验。一般而言,对于启用 CloudFront 的内容,第一次 GET 请求的速度略微快于未启用 CloudFront 的请求;但之后的每次 GET 请求的速度则显著提升。这归因于缓存。在第一次 GET 请求后,从我的 S3 存储桶分发的文件将被缓存,现在已经存储在最靠近测试地点的边缘站点中。有时,文件返回的速度提高了 100 倍!

是不是非常直接明了? 希望您已经了解为 S3 配置 CloudFront 是多么方便,并且熟悉了这样操作的两大优势:1) 通过以远远更快的速度服务用户,从而提高应用程序的性能;2) 借助 CloudFront 的安全功能提高应用程序的安全性。嗯,值得再次强调的是,从 CloudFront 向 Internet 传输数据的价格往往要低于从 S3 向 Internet 传输,因此您甚至还可以降低您的 AWS 费用!