高可用性架构
概览
AWS 边缘服务是用来构建具有高可用性的 Web 应用程序的重要组件。AWS 边缘服务本质上是分布式服务,因此具有原生高可用性,此外,这些服务还充当 Web 应用程序的接入点,可以将请求路由到您的来源基础设施(例如可用区或区域)中的可用分区。
架构决策
根据您在可用性 SLO、成本和复杂程度方面的要求,可以采用多种方式架构高可用性 Web 应用程序。您至少需要根据业务需求做出以下技术决策:
- 您拥有主动/主动还是主动/被动架构?
- 您是否拥有不同的来源?不同的可用区?不同的区域?
- 主动/主动架构的跨来源路由逻辑是什么? 主动/被动架构的失效转移标准是什么?
管理瞬态来源错误
CloudFront 可以帮助减轻瞬态 5xx 错误的影响,这些错误有时会妨碍少量用户请求。这种情况通常是流量突然达到峰值导致来源不堪重负而造成的,或者是由瞬态网络问题所致。可以使用 CloudFront,通过不同的方式缓解瞬态 5xx 错误。
重试。可以使用一个可配置的连接超时时间,将 CloudFront 配置为在无法与来源建立连接时重试最多三次 TCP 连接。CloudFront 还会根据所配置的重试次数重试幂等 GET/HEAD。
使用陈旧的内容进行响应。如果重试连接到来源失败,而且缓存中存在陈旧版本的对象,CloudFront 会默认提供此对象,而不是返回一个错误响应。可以使用 Cache-Control: stale-if-error=0 指令禁用这一行为。
来源失效转移到辅助来源。可以使用来源失效转移功能将 CloudFront 配置为在特定的请求失败时转移到辅助来源。来源失效转移只适用于幂等 GET/HEAD 请求。请注意,如果对来源事件使用 Lambda@Edge,CloudFront 也会对失效转移操作执行此函数。在这种情况下,可以在 Lambda@Edge 函数中推断请求是针对主要来源还是辅助来源,以区分它的逻辑。为此,在这两种来源中配置了相同的来源自定义标头,但具有可供 Lambda@Edge 读取的不同值。
正常的失效转移。如果不希望将来源失效转移到另一个来源(例如当维护另一个来源基础设施时),请考虑使用自定义错误页面,以便在发生失效时转移到另一个位置(例如 S3 存储桶)托管的一个静态文件。默认情况下,同一个页面将应用于所有导致错误的请求,但可以按照此博客中的第三种模式构建一个更加动态的响应。
来源中断期间的有状态失效转移
基于 Route 53 策略的失效转移
对于被配置为 CloudFront 中的来源的来源域名,可以将 Route 53 失效转移路由策略与运行状况检查结合使用。当主要来源不正常时,Route 53 会检测到这一情况,然后开始使用辅助来源的 IP 地址解析来源域名。CloudFront 将等待来源 DNS TTL 结束,这意味着流量将开始流向 DNS TTL 内的辅助来源。最佳配置(已激活快速检查,失效转移阈值为 1,DNS TTL 为 60 秒)意味着至少需要等待 70 秒钟才会执行失效转移。当执行失效转移时,所有流量都将切换到辅助来源,因为这是一次有状态的失效转移。请注意,可以通过 Route 53 应用程序恢复控制进一步扩展这一设计,以便在多个 AWS 区域、可用区和本地执行更复杂的应用程序失效转移。这种方法可以与用于 GET/HEAD 请求的 CloudFront“来源失效转移”功能结合使用,以减少在 Route 53 失效转移到辅助来源时出现的错误。此博客中介绍了这种模式。

当不同的来源(例如基于 S3 的来源)不共享同一个域名时,将无法按照所建议的上述方式使用 Route 53。在这种情况下,需要使用一个为来源请求事件配置的 Lambda@Edge 函数来查询要为其选择来源的 Route 53,然后通过更改来源域名和主机标头将请求重新路由到所选的来源。要了解有关此实施的更多信息,请阅读下面的 Contentful 案例研究。
使用 Global Accelerator 进行失效转移
使用 Global Accelerator 的应用程序可以从其原生失效转移功能受益。使用 Global Accelerator,可以将应用程序部署在跨多个可用区或跨多个 AWS 区域的单个 AWS 区域中。Global Accelerator 利用运行状况检查功能监控应用程序端点的运行状况,并在数十秒内将异常端点的流量路由到其他位置。
主动–主动架构
基于延迟的路由
可以将 CloudFront 与 Route 53 基于延迟的策略结合使用,以便将用户请求路由到您在主动–主动多区域架构中为其复制了来源的最近 AWS 区域。为此,请使用 Route 53 中基于延迟的策略配置 CloudFront 中的来源域名。当 CloudFront 解析来源域名以连接到此来源并将请求发送到此来源时,Route 53 将根据延迟返回最近的来源 IP。请注意,CloudFront 从中解析来源域名的位置取决于分发配置和流量类型。对于动态请求,通常在边缘站点解析域名,对于可缓存的内容,通常在区域边缘缓存中解析域名。此博客将指导您完成 API Gateway 的主动–主动多区域部署。

当不同的来源(例如基于 S3 的来源)不共享同一个域名时,将无法按照所建议的上述方式使用 Route 53。在这种情况下,需要使用一个为来源请求事件配置的 Lambda@Edge 路由到最近的来源。要了解有关此实施的更多信息,请阅读以下博客:
- 使用 Amazon CloudFront 和 Amazon S3 构建多区域主动–主动地理邻近应用程序
- 将多区域 API 与 CloudFront 结合使用,以减小最终用户的延迟。 在此博客中,您将了解如何实施基于多区域 AppSync 的 GraphQL API。
高级路由
在某些情况下,需要使用应用程序级逻辑来路由请求。如果逻辑比较简单,例如根据路径路由到不同的来源(例如将 /api1 路由到来源 1、将 /api2 路由到来源 2),只需使用 CloudFront 的原生缓存行为功能。
如果路由逻辑更复杂(例如基于用户订阅等级),则可以使用 CloudFront 的 Edge 函数。使用 CloudFront Functions,可以从 KeyValueStore 获取路由定义,并使用 updateRequestOrigin() method 方法更改路由。如果路由逻辑需要访问外部来源,请在来源请求事件上使用 Lambda@Edge,并在函数处理程序中更新事件对象的来源属性。
