无论您是通过 Amazon Elastic Load Balancer (Amazon ELB)、Amazon Elastic Compute Cloud (Amazon EC2) 实例、Amazon API Gateway 还是 AWS Lambda 向互联网上的最终用户提供动态内容,您都可以通过将 Amazon CloudFront 作为内容分发网络 (CDN) 来提高性能、安全性,并优化内容交付的成本。动态内容是指任何对每个用户或甚至每个请求都是唯一的 Web 对象,因此无法受益于缓存。示例包括 API 调用和个性化内容,如在线购物车或定向广告。
在本文中,您将了解 CloudFront 为您的动态工作负载带来的好处,从成本优化、性能和安全架构支柱的角度进行回顾。您还将熟悉配置最佳实践。
性能
内容交付性能是指客户端与服务器之间传输的IP包的低延迟和高吞吐量。
对于静态内容,这在很大程度上是通过在CloudFront边缘位置缓存静态对象,靠近用户来实现的。通过从边缘提供内容,我们减少了客户端和服务器之间 IP 包必须传输的网络距离。这促使更低的延迟、更高的吞吐量,并且总体上提供了更好的用户体验。
虽然这不适用于无法缓存的动态内容,但缓存并不是使用 CloudFront 提高性能的唯一因素。您还应该考虑其他有助于性能的因素,这些因素同样适用于静态和动态内容。
CloudFront对静态内容的性能优势之一是源站卸载:当内容缓存到CloudFront时,大部分请求将从边缘位置提供,而无需访问源站。虽然我们无法缓存动态内容,但通过利用 CloudFront 的持久连接功能,我们仍然能够实现源站卸载。该功能允许来自用户的请求重用先前请求已创建的与源站的现有 TCP 上行连接。这消除了每个用户都需要进行源站的TCP和TLS握手的需求。上行连接重用的效果,以及它对整体性能的影响,可以通过CloudFront的 Server-Timing 标头功能进行测试和演示。该功能使您能够从CloudFront的响应中接收一些诊断信息,包括 cdn-upstream-connect 指标。该指标包含一个值,表示从源站 DNS 请求完成到与源站建立 TCP(和 TLS,如果适用)连接完成之间的毫秒数。值为零(0)表示 CloudFront 重用了现有连接。因此,通过发送多个请求并分析 Server-Timing 标头,我们可以看到有多少请求重用了连接。在 Curl 及其输出功能的进一步帮助下,我们可以测量客户端的一些其他时间,如下载时间,并了解连接重用的影响。
我们需要一个测试环境来进行测试,为此我们模拟了一个动态工作负载,包含 CloudFront 分发和一个运行在 CloudFront 分发后面的 Nginx 服务器的 Amazon EC2。此 EC2 使用一个名为 CachingDisabled 的托管缓存策略,非常适用于动态内容。此外,我们进行测试并展示结果。请注意,实际的延迟数字是特定于测试客户端的。您可以通过部署 GitHub 上提供的测试系统进行自己的测试,或者仅使用其中的 Curl 脚本,通过启用 Server-Timing 标头来测试您的 CloudFront 分发。该测试系统使用了一些我们将在本文的安全部分进一步讨论的安全最佳实践。特别是,ALB 和 EC2 安全组仅允许来自 CloudFront 分发的请求,禁用了来自互联网的任何直接请求。

首先,通过运行测试脚本发送 10 个请求:
python3 timings.py -url https://d1234.cloudfront.net -n 10

从结果中可以看出,10个请求中有6个请求的上游连接时间为零。这意味着连接被重用了,换句话说,连接是预热的。在这个例子中,我们可以看到,预热连接的下载时间比初始连接平均减少了39%。除了减少 TLS 和 TCP 握手的开销外,预热连接还具有更大的拥塞窗口(Congestion Window,CWND),从而实现更高的吞吐量。
如果我们发送更多的请求,例如100个请求,那么我们可以看到连接重用率会增加:
python3 timings.py -url https://d1234.cloudfront.net -n 100

现在,连接重用率达到了93%,并且随着请求数量的增加,它还可以进一步提高。连接重用不仅降低了延迟(特别是对于像测试中使用的小文件),还减轻了源站的负担,让我们能够减少源站的计算资源使用。如果没有 CloudFront,所有终端用户的请求都会直接到达 ALB,这就会导致每个用户都需要建立一个新的连接,从而产生更多的 LCU(负载均衡容量单位)并增加成本。
性能基准测试的说明
从测试中可以看出,连接重用对少量请求没有影响,而大约在10个请求后才开始体现其效果。这使得任何只生成一两个探测请求的合成测试对于由大量请求组成的生产流量来说是没有意义的,因为连接重用的效果会在这些流量中触发。因此,我们建议使用生产流量进行性能基准测试。您可以将流量在被测试的系统之间进行50/50的分配,或者每周或每天交换流量进行测试。
Origin Shield 提高连接重用率
Origin Shield是CloudFront的一种解决方案,它将所有请求路由到一个单一的区域边缘缓存,该缓存负责从源站获取内容。虽然Origin Shield主要是为了最大化缓存比例,但它也能提高连接重用率。这是因为请求到达已经建立的连接的机会在Origin Shield中更高,因为它是唯一与源站交互的缓存层。如果您希望进一步提高连接重用率,我们建议在您的CloudFront分发中启用Origin Shield。如果您的内容受众遍布全球,您可以通过启用Origin Shield,将请求集中到相同的区域边缘缓存,并测试是否会进一步提高连接重用率。
AWS 全球网络
AWS 全球网络是亚马逊自有的高度可用、低延迟的网络,它将 CloudFront 边缘位置连接到 AWS 区域。由于 Amazon 完全拥有该网络,我们根据需求扩展它,确保它有足够的容量承载客户流量。当您通过 CloudFront 提供动态内容时,流量会通过 CloudFront 边缘位置从公共互联网转移到 AWS 全球网络,边缘位置充当入口点。CloudFront 边缘位置还与每个区域内的所有主要 ISP 进行良好互联,确保与终端用户网络的良好连接。在互联网中,通常有多个路径可以发送数据包到达相同的源和目标。没有使用自有网络的 CDN 可能会基于不同网络路径的实时性能测量开发覆盖互联网的路由,并向客户收取额外费用。对于 CloudFront 来说,这一功能是其数据包路由机制的本地特性,考虑到 Amazon 网络的拥塞状态,只会通过没有拥塞的链路路由流量。即使某个边缘位置和区域之间的链路发生意外的流量激增或网络故障,当主链路受到影响时,仍然会有备用路径能够接管流量。虽然这一特性并不总是带来更好的性能,尤其是当用户已经接近源站且网络连接没有遭遇拥塞时,但使用托管网络的能力始终是一个优势。这通常意味着更少的丢包,进而减少了重传、更稳定的抖动,以及整体更好的体验质量。
其他性能改进技术
CloudFront 支持使用高性能协议,如 HTTP/2 和 HTTP/3、先进的 TCP 拥塞控制算法 TCP BBR,以及更快的 TLS 1.3(支持会话恢复)。特别是,HTTP/3 与 HTTP/1.1 和 HTTP/2 不同,它使用基于 UDP 的 QUIC 协议,克服了 TCP 的一些限制,促使更快的连接建立和更高效的带宽利用率,因为它对数据包丢失的依赖较小。启用 HTTP/3 的 CloudFront 客户已经看到延迟改善最多可达 10%。
安全性
您必须提高动态内容的安全性,因为诸如API端点、登录服务等应用程序通常容易成为恶意流量的攻击目标。大多数静态内容的请求将从边缘位置提供,这有助于吸收DDoS攻击。然而,所有动态内容的请求,无论是合法的还是恶意的,都会直接到达源站,除非在此之前已经检测并缓解了恶意流量。CloudFront可以通过多种方式帮助您提高应用程序的安全性。
L3/L4 Inline DDoS 缓解系统
当您通过CloudFront提供您的Web应用程序时,所有发送到应用程序的数据包都会被一个完全Inline的DDoS缓解系统检查,这不会引入可观察的延迟。针对 CloudFront分发的L3/L4DDoS攻击会实时缓解。对于区域性资源(未使用CloudFront),检测逻辑有所不同:数据包不会内联检查,而是直接从互联网到达应用程序。相反,这些资源会监控流量的升高,以识别可能需要缓解的 DDoS 攻击。每分钟会评估每个 AWS 资源的流量。这意味着与使用 CloudFront 时的检测和缓解速度相比,这种方式的检测和缓解速度会稍慢。
访问控制
CloudFront 要求源站使用公共 IP。然而,CloudFront 还允许您仅允许来自 CloudFront IP 的流量,并阻止任何其他直接到达应用程序的流量。为此,您可以在保护源站的 VPC 中的安全组配置中包含 CloudFront 托管的 IP 前缀列表。此外,我们建议配置 CloudFront 发送自定义 HTTP 标头,并配置源站(如 ALB)验证标头及其值的存在,如果验证失败,则阻止请求。通过这种方式,您将只允许来自您 CloudFront 分发的流量,并且您还可以配置用户访问控制:签名 URL 或签名 cookies 和地理阻止(Geo Blocking)。
实施边界防护
边界防护服务,如 AWS WAF 和 AWS Shield Advanced,帮助您减少可能淹没应用程序的不良流量。AWS WAF 基于速率的规则、Bot控制、ATP、Shield 自动应用层 DDoS 缓解,以及 CloudFront Functions 用于验证和授权请求,都可以在边缘有效地阻止不良流量。然而,一些 AWS 服务并不直接支持 AWS WAF 或 Shield Advanced。例如,API Gateway 不支持 Shield Advanced,而 AWS Lambda URL 不支持 AWS WAF。您可以通过将这些使用服务的应用程序前置于 CloudFront 并将 Shield Advanced 和 AWS WAF 保护应用到 CloudFront 分发来提高其安全性。通过在 CloudFront 和服务之间实施 API 密钥或秘密标头,您可以使其变为非公开,并且在使用 HTTPS 时难以被截获。

成本效益
CloudFront可以降低您的数据传输出(DTO)成本。从任何AWS源站到CloudFront的DTO不会产生费用,但CloudFront的DTO会产生费用。换句话说,来自AWS源站的DTO成本将被CloudFront的DTO成本所取代,而后者的费用更低,如果您愿意承诺最低流量(通常为每月10TB或更高),或者使用 CloudFront的Savings Bundle,费用还可以进一步降低。CloudFront还提供了免费套餐,每月包括1TB的数据传输到互联网,以及1000万次HTTP或HTTPS 请求的免费额度。CloudFront DTO只计算响应的字节,不包括交换TLS证书,而例如EC2的DTO会计算所有经过的数据字节,包括TLS部分。正如我们所展示的,使用持久连接的源站卸载可以帮助您降低ALB LCU成本。请注意,当受保护的资源是CloudFront 分发时,Shield Advanced的DTO成本目前比在 Amazon EC2 或 ALB 上应用保护时低一半。最后,您订阅的Shield Advanced包括 AWS WAF 的基础费用,用于 Web ACL、规则和 Web 请求。

请注意,像Lambda@Edge、CloudFront Functions、实时日志、Origin Shield 和超过失效请求配额等可选的 CloudFront 功能不包含在流量费用中,它们会单独计费。
结论
在本文中,您了解了 CloudFront 为您的动态内容带来的好处。CloudFront 可以在多方面帮助您:加速内容交付,保护您的应用免受恶意流量的攻击,并降低 DTO费用。启用CloudFront 时,请考虑测试性能改进、安全性以及成本影响,以评估其对您特定动态工作负载的影响。