amazon-web-services - 如果未找到文件,则禁用 Cloudfront 缓存
问题描述
我在 S3 存储桶前创建了一个 Cloudfront 分发,如果未找到请求的文件,则使用 RoutingRule 重定向到 lambda 函数。我正在使用它来调整图像大小。
所需流量:
- 向 Cloudfront 请求文件
- 在 Cloudfront 检查 S3 中找不到文件
- 在 S3 中找不到文件重定向到 lambda 函数
- 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 函数。
- 我确认 lambda 函数生成了该文件。
- 如果我使 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 网关调用的故障转移。
解决方案
当然,您可以使用 Lambda@Edge Origin Response 触发器来修改响应并设置所需的标头。从某种意义上说,这将是“最正确”,因此也是“最理想”的解决方案,但仅在理论上,因为它引入了不必要的成本和复杂性。
默认 TTL 是 CloudFront 在内部使用的值,当没有Cache-Control
找到响应标头时...因此,您可以将其设置为 0 并Cache-Control
在创建 S3 对象时包含正确的标头,这样就不会使用默认 TTL除了重定向。我不喜欢的是没有标题坚持浏览器也不缓存重定向。
但是您实际上并不需要在此处将重定向返回给浏览器。您根本不需要重定向。
借助 CloudFront 的源故障转移功能,您可以为您的分配设置两个源 - 主源和辅助源,以便在 CloudFront 检测到您的主源不可用时从您的辅助源提供您的内容。
在这里,“不可用”这个词是不必要的模糊,因为这个功能做的不止这些,它会做你想做的事。要设置触发源“故障转移”的内容...
您可以选择以下状态代码的任意组合:500、502、503、504、404 或 403。
因此,只需正常的存储桶行为就足够了,不需要重定向规则。
请注意,使用此设置,最终响应是 CloudFront 可以缓存的唯一内容——无论该响应来自主要 (S3) 还是次要(通过 API 网关的 Lambda)源——因此这消除了瞬态响应的问题被缓存。
另请注意,尽管使用了“故障转移”一词,但 CloudFront 并不维护源状态的概念模型,因此每个请求都是独立的,即使其他请求“失败”也会转到主源。
推荐阅读
- linq - 是否有某种方法可以简化对 LINQ GroupBy 查询中组的第一个成员的访问?
- reactjs - Mapbox 和 CSS Grid - Mapbox 不会在调整窗口大小时自动扩展
- typescript - WebStorm“eslint --fix on save”功能不起作用。但在终端 ESLint 运行良好
- c# - 使用 AzukeKeyVault 密钥签署 JWT
- c++ - 为非标准相机实现 Qt 相机插件
- python - django-background-task 执行完成后如何释放内存资源?
- java - 如何阻止一个微服务消费消息队列中的消息-RabbitMQ
- npm - SyntaxError:尝试将所有 .js 文件的扩展名更改为 .ts 时意外导入令牌
- testing - DBT中的暴露
- r - 使用 tidyverse 更广泛地旋转