我们正在使用 CloudFront 来存储静态资产,但也希望允许使用 Gzip。我们设置了一个新的分发版,其中自定义源指向位于弹性负载均衡器后面的应用程序服务器。我们手动保持文件在集群中同步,并在发布时更新它们。
但是,通过这种设置,我们从 CloudFront 中得到的只是 Miss 和 RefreshHits,到目前为止,这已经违背了目的。是否有任何其他设置才能使用 ELB 作为自定义源?在文档中,它将其作为可行的解决方案引用。
当我们将分发指向生产集群中的单个服务器时,cloudfront 会正确缓存我们的资产。
粘性会话 cookie 以及其添加的后续标头是否有可能成为问题?
Cache-Control: no-cache="set-cookie"
//由负载均衡器添加
有任何想法吗?
仅供参考 - 目前,我们的自定义原点指向单个 EC2 实例,因此缓存工作正常 - 以防您尝试卷曲下面的文件。
示例标题:curl -Ihttp://static.quick-cdn.com/css/9850999.css
HTTP/1.0 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=3700
Cache-Control: no-cache="set-cookie"
Content-Length: 23038
Content-Type: text/css
Date: Thu, 12 Apr 2012 23:03:52 GMT
Last-Modified: Thu, 12 Apr 2012 23:00:14 GMT
Server: Apache/2.2.17 (Ubuntu)
Vary: Accept-Encoding
X-Cache: RefreshHit from cloudfront
X-Amz-Cf-Id: K_q7Zy3_jdzlEJ85ukELVtdx1GmuXqApAbZZ7G0fPt0mxRMqPKX5pQ==,RzJmPku-rEIO9WlvuSoKa8hiAaR3dLk5KC4cQMWWrf_MDhmjWe8n6A==
Via: 1.0 28c34f9fbf559a21ee16594849e4fc9c.cloudfront.net (CloudFront)
Connection: close
答案1
CloudFront 可能无法正确处理具有相同名称的多个标头,并且无法看到您的max-age
指令。根据这CloudFront 使用Expires
标头,因此请尝试让您的源服务器设置该标头(最好相对于请求时间)。对于 Apache,我认为您需要类似这样的内容mod_expires:
ExpiresDefault "access plus 1 hour"
答案2
在 ELB 上使用粘性会话时,负载均衡器将在响应中添加以下两个标头:Set-Cookie
(带有 AWSELB cookie)和Cache-Control: no-cache="set-cookie"
。
如果您的 CF Distro 上的 min-ttl 为 0(现在是默认值),CloudFront 将使用 no-cache 指令。亚马逊代表给我发了以下链接:w3.org-RFC2616。
以下来自 no-cache 部分的描述适用:
如果 no-cache 指令确实指定了一个或多个字段名,则缓存可以使用响应来满足后续请求,但须遵守缓存的其他任何限制。但是,在未成功与源服务器重新验证的情况下,指定的字段名不得在后续请求的响应中发送
但是,根据我的经验,如果设置了该指令,CloudFront 始终会重新验证对象。我相信,他们实际上应该省略一开始no-cache
就指定的 Set-Cookie 标头。no-cache
快速修复方法是创建一个新的 CF Distro 并手动指定大于 0 的 min-ttl,这似乎会覆盖该no-cache
指令。您需要使用 API 或第三方程序来执行此操作,因为 AWS 控制台不允许您修改 min-ttl。