AWS Cloudfront Origin Groups“不能包含缓存行为的 POST、PUT、PATCH 或 DELETE”

Gre*_*ray 8 amazon-web-services amazon-cloudfront

我的 CloudFront 发行版中有两条路径,它们具有以下行为:

路径模式 起源 查看器协议政策
/API/* API起源组 将 HTTP 重定向到 HTTPS
/* S3起源集团 将 HTTP 重定向到 HTTPS

以及这些起源:

产地名称 源域 奥瑞金集团
S3起源1 us-east-1.s3.[废话] S3起源集团
S3起源2 us-east-2.s3.[废话] S3起源集团
API来源1 一个域 API起源组
API起源2 一个域 API起源组

此设置适用于 GET 请求,但如果我将 POST 请求添加到Cache Behaviour的缓存方法中,则会收到错误:

“不能包含缓存行为的 POST、PUT、PATCH 或 DELETE”

这对我来说没有意义。如果 AWS 客户确实使用 CloudFront每天处理数十亿个请求,并且 AWS 建议使用 CloudFront 源故障转移(这“需要源组”),那么就必须有某种方法来配置 CloudFront 以允许允许 POST 请求的源行为。这不是真的吗?所有这些 API 请求都是由该客户 GET 请求发出的吗?

需要明确的是,我的根本问题是,当 AWS 区域出现故障时,我想使用 CloudFront Origin Failover 在主要区域和次要区域之间切换。为了实现这一点,我不仅需要切换基于 S3 的前端流量(GET 请求),还需要切换后端流量(POST 请求)。

注意:如果您不使用源组,CloudFront 支持 POST 请求的路由行为。看来只有当我添加这个Origin Group(以支持第二个区域)时,才会出现这个错误。

Rah*_*rma 8

简短回答:您无法在 CloudFront 中对GETHEAD或之外的请求方法执行源故障转移OPTIONS。时期。

TL; DR

CloudFront始终缓存GET和请求。HEAD它也可以配置为缓存OPTIONS请求。但是,它不会缓存POSTPUTPATCHDELETE、... 请求,这与大多数公共 CDN 一致。但是,其中一些可能会为您提供编写某种自定义挂钩的功能,您可以通过这些挂钩来缓存POSTPUTPATCHDELETE、... 请求。您可能想知道这是为什么?为什么我无法缓存POST请求?这个问题的答案是RFC 2616。由于POST请求不是幂等的,因此规范建议不要缓存它们并将它们发送到预期的终端服务器,事实上,总是如此。这里有一个非常好的SO 线程,您可以阅读它以更好地理解。

CloudFrontHTTP仅当查看器请求的方法为GETHEAD或时,才会故障转移到辅助源OPTIONSPOST当查看器发送不同的 HTTP 方法(例如、PUT等)时,CloudFront 不会进行故障转移。

好的。POSTCloudFront 不会缓存请求。但是,为什么 CloudFront 不为POST请求提供故障转移?

让我们看看在主源发生故障时 CloudFront 如何处理请求。见下文:

在此输入图像描述

CloudFront将所有传入请求路由到主源,即使先前的请求故障转移到辅助源也是如此。CloudFront仅在对主源的请求失败后才向辅助源发送请求。

现在,由于POST未缓存请求,CloudFront因此每次都必须转到主源,返回无效响应或最糟糕的超时,然后命中源组中的辅助源。我们在这里讨论的是区域故障。从主节点到辅助节点的故障转移请求会高得离谱,我们可能会预期由于高负载会出现级联故障。这会导致 CloudFront PoP 失败,从而违背了高可用性的全部目的,不是吗?再次强调,这个解释只是我的假设。当然,我确信 CloudFront 的人员很快就会想出一个处理POST请求区域故障转移的解决方案。

到目前为止,一切都很好。但其他 AWS 客户如何在 AWS 区域发生故障时保证其用户的高可用性。

GET其他 AWS 客户仅使用 CloudFront 区域故障转移来制作静态网站、SPA、视频(直播和点播)、图像等静态内容,顺便说一句,这仅需要 且偶尔会HEAD请求OPTION HTTP。想象一下一家 SaaS 公司通过静态网站推动其销售和发现。如果您可以通过上述方法减少停机时间,从而确保您的销售/增长不会受到影响,为什么不呢?

明白了。但我确实需要为我的后端 API 提供区域故障转移。我该怎么做?

一种方法是编写自定义Lambda@Edge函数。CloudFront命中预期的主要源,内部代码检查超时/响应代码/等,如果必须触发故障转移,则命中其他源的端点并返回响应。这又与目前的方案相矛盾CloudFront

另一种解决方案是利用 Route53 的基于延迟的路由支持,在我看来更简洁。您可以在此处阅读有关如何执行此操作的信息。如果您的 S3 文件和 API(以及指向不同发行版的子域)有不同的子域名,则此方法肯定适用于您的后端 API,CloudFront因为它利用CloudFront规范名称,但我有点怀疑这是否适用于您的设置。无论如何,你可以尝试测试一下。

编辑:根据OP的建议,还有第三种方法可以实现此目的,即在客户端处理此问题。每当客户端收到意外响应代码或超时时,它都会对托管在另一个区域的另一个端点进行 API 调用。该解决方案更便宜、更简单,并且更容易使用当前可用的方案来实现。