首页 > 解决方案 > 如果未找到文件,则禁用 Cloudfront 缓存

问题描述

我在 S3 存储桶前创建了一个 Cloudfront 分发,如果未找到请求的文件,则使用 RoutingRule 重定向到 lambda 函数。我正在使用它来调整图像大小。

所需流量:

  1. 向 Cloudfront 请求文件
  2. 在 Cloudfront 检查 S3 中找不到文件
  3. 在 S3 中找不到文件重定向到 lambda 函数
  4. Lambda 将找到原始文件,调整其大小并重定向回 Cloudfront url。

s3网站上的重定向规则集:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals/>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>mylambda.execute-api.us-east-1.amazonaws.com</HostName>
      <ReplaceKeyPrefixWith>/?key=</ReplaceKeyPrefixWith>
      <HttpRedirectCode>307</HttpRedirectCode>
    </Redirect>
  </RoutingRule>
</RoutingRules>

当 lambda 函数重定向回原始 url Cloudfront 缓存 404 时,第 4 步出现问题?并且来自 S3 的路由规则再次重定向到导致循环的 lambda 函数。

  1. 我确认 lambda 函数生成了该文件。
  2. 如果我使 Cloudfront 上的文件无效,我成功地看到它是从 S3 提供的)

我尝试将 0 TTL 添加到 404 错误页面,但没有帮助。

自定义错误响应

重定向规则返回 307 状态代码[Temporary Redirect]。但我不知道如何为此设置 0 TTL。我在 Cloudfront 自定义错误响应页面上找不到该选项。

在此处输入图像描述

根据这篇文章。307 被缓存。需要为它设定一个规则......某处。

这是关于 AWS S3 静态网站托管上的 RoutingRules的后续问题

我感谢您的帮助。

更新: 1. 删除 S3 上的 RoutingRule 2. 向 Cloudfront 分发(API 网关)添加了一个新源

在此处输入图像描述

lambda 函数现在返回

    return {
        statusCode: "200",
        body: "image converted",
    };

检查 Cloudwatch 日志我没有看到 lambda 函数被调用,当我转到https://myCloudfront.cloudfront.net/photos/resized/test.jpg

我只看到一个普通的 404

在此处输入图像描述

我还为 404 添加了一个 0 TTL 的自定义错误页面

好消息是,如果我通过 key=/photos/resized/test.jpg 转到 api 网关,然后转到https://my.cloudfront.net/photos/resized/test.jpg它可以工作。它正确读取图像。

我认为问题在于未触发 api 网关调用的故障转移。

在此处输入图像描述

标签: amazon-web-servicesamazon-s3amazon-cloudfront

解决方案


当然,您可以使用 Lambda@Edge Origin Response 触发器来修改响应并设置所需的标头。从某种意义上说,这将是“最正确”,因此也是“最理想”的解决方案,但仅在理论上,因为它引入了不必要的成本和复杂性。

默认 TTL 是 CloudFront 在内部使用的值,当没有Cache-Control找到响应标头时...因此,您可以将其设置为 0 并Cache-Control在创建 S3 对象时包含正确的标头,这样就不会使用默认 TTL除了重定向。我不喜欢的是没有标题坚持浏览器也不缓存重定向。

但是您实际上并不需要在此处将重定向返回给浏览器。您根本不需要重定向。

借助 CloudFront 的源故障转移功能,您可以为您的分配设置两个源 - 主源和辅助源,以便在 CloudFront 检测到您的主源不可用时从您的辅助源提供您的内容。

https://aws.amazon.com/about-aws/whats-new/2018/11/amazon-cloudfront-announces-support-for-origin-failover/

在这里,“不可用”这个词是不必要的模糊,因为这个功能做的不止这些,它会做你想做的事。要设置触发源“故障转移”的内容...

您可以选择以下状态代码的任意组合:500、502、503、504、404 或 403。

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html#concept_origin_groups.creating

因此,只需正常的存储桶行为就足够了,不需要重定向规则。

请注意,使用此设置,最终响应是 CloudFront 可以缓存的唯一内容——无论该响应来自主要 (S3) 还是次要(通过 API 网关的 Lambda)源——因此这消除了瞬态响应的问题被缓存。

另请注意,尽管使用了“故障转移”一词,但 CloudFront 并不维护源状态的概念模型,因此每个请求都是独立的,即使其他请求“失败”也会转到主源。


推荐阅读