【问题标题】:Are AWS Cloudfront custom error pages slow?AWS Cloudfront 自定义错误页面是否很慢?
【发布时间】:2020-07-29 02:59:55
【问题描述】:

我有一个托管在 S3 上并使用 Cloudfront 提供服务的单页应用程序。一切正常,但我试图通过缓存 Cloudfront 上的所有文件来提高应用程序首次加载的性能。现在所有文件都非常快速地提供,除了一个:页面 HTML。只有一个 HTML 文件 (/index.html),每次使用 Cloudfront 上的自定义错误页面无法在源 (S3) 上找到该文件时都会提供该文件。例如,此文件在我的域的根目录上提供。

我设置了自定义错误页面的错误缓存最小 TTL,以将响应缓存 1 天(86400 秒),如图所示。 Cloudfront customer error page settings

然而,这个缓存配置似乎没有任何效果。每次 URL 不存在于源上(并且 S3 返回状态 403)时,响应都是正确的,但 Cloudfront 会在 x-cache 标头上指示 Miss 并且需要大约 500 毫秒的响应时间。如果文件是通过我的域上的路径“/index.html”请求的,Cloudfront 会在 x-cache 标头上指示命中并在 20 毫秒内响应。

index.html 文件的缓存控制标头设置为最大年龄等于 Cloudfront 错误缓存最小 TTL。

是我遗漏了什么还是 Cloudfront 自定义错误页面太慢了?

【问题讨论】:

  • 我也遇到了这个问题。我的理论是,因为 S3 正在返回错误页面的动态内容,CloudFront 实际上无法缓存自定义错误页面,因为它每次都在检查源 (S3)。

标签: amazon-web-services amazon-s3 amazon-cloudfront


【解决方案1】:

通过将 S3 存储桶策略设置为在存储桶资源本身中包含 "s3:ListBucket",可以解决此问题。例如,

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity INSERT-CLOUDFRONT-OIA-ID"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::EXAMPLE-BUCKET/*",
                "arn:aws:s3:::EXAMPLE-BUCKET"
            ]
        }
    ]
}

不同之处在于错误页面随后将具有 404 HTTP 状态代码(来自 S3)而不是 403(来自 S3),这意味着 CloudFront will actually respect the cache TTL of the custom error page 因此它不会再次命中原始 (S3)。

在此更改之后,我在 CloudFront 上的非根 / 路由上看到了 10 毫秒的响应时间。

此更改的

重要的副作用是人们理论上可以使用ListObjects API 查看您存储桶的目录列表,例如http://EXAMPLE-BUCKET.s3.amazonaws.com/?delimiter=/,因此使用 OAI (Origin Access Identity) 保护 S3 存储桶仅可从 CloudFront 访问非常重要(ListObjects URL 不起作用)。

【讨论】:

    【解决方案2】:

    我看到来自印度客户/用户的第 100 层(美国、欧盟地区)Cloudfront 的 TTFB(第一个字节的时间)大约 800 毫秒。

    解决方案 1 - Cloudfront 函数

    在 Cloudfront 函数的帮助下,这个值减少到大约 180 毫秒。延迟与默认 index.html 所用的时间相同。

    这是它的代码。

    function handler(event) {
        var request = event.request;
        var uri = request.uri;
    
        if (!uri.includes('.')) { // update with your own logic
            request.uri = '/index.html';
        }
        return request;
    }
    
    

    这将减少 TFFB,但会开始对 CloudFront 的请求总数产生影响。每百万次调用 0.10 美元。

    解决方案 2 - 生成路由

    从应用程序中,如果我们有一个用户可以访问的路线列表,您可以创建 s3 目录并复制 index.html 。这种方法需要您控制应用。

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 2021-07-14
      • 1970-01-01
      • 2020-02-01
      • 2018-10-03
      • 1970-01-01
      • 2011-04-20
      • 2015-08-26
      • 1970-01-01
      相关资源
      最近更新 更多