【问题标题】:Nginx not caching requests coming through ELBNginx 不缓存来自 ELB 的请求
【发布时间】:2014-11-17 21:08:22
【问题描述】:

我在 ELB 之间安装了 nginx。我在 ELB 后面有几个应用程序池,nginx 将流量传回,我想缓存静态内容。我的问题是 nginx 似乎没有缓存任何响应。这是缓存配置:

proxy_cache_path  /usr/share/nginx/cache/app levels=1:2 keys_zone=cms-cache:8m max_size=1000m inactive=600m;
proxy_temp_path /usr/share/nginx/cache/;

  location / {
    proxy_pass  http://cms-pool;
    proxy_cache cms-cache;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
  }

经过阅读后,我发现可能有一些标题导致了问题,但在隐藏了明显的标题后,我没有运气,最终破坏了应用程序,因为我隐藏了所有后端 cookie。这些是我尝试删除的标题:

proxy_ignore_headers Cache-Control Expires Set-Cookie;
proxy_hide_header Cache-Control;
proxy_hide_header Set-Cookie;

我现在不知道为什么没有缓存请求,这是通过上述标头配置获得的标头 curl 的输出(cookie 等是从前面的 nginx/elb 设置的nginx):

Accept-Ranges: bytes
Connection: keep-alive
Content-length: 6821
Content-Type: text/html
Date: Sun, 16 Nov 2014 19:25:41 GMT
ETag: W/"6821-1415964130000"
Expires: Thu, 01 Jan 1970 00:00:00 GMT
HTTP/1.1 200 OK
Last-Modified: Fri, 14 Nov 2014 11:22:10 GMT
Pragma: no-cache
Server: nginx/1.7.6
Set-Cookie: AWSELB=4BB7AB49169E74EC05060FB9839BD30C2CB1D0E43D90837DC593EB2BA783FB372E90B6F6F575D13C6567102032557C76E00B1F5DB0B520CF929C3B81327C1D259A9EA5C73771C4EA3DB6390EB40484EDF56491135B;PATH=/
Set-Cookie: frontend=CgAAi1Ro+jUDNkZYAwMFAg==; path=/

更新我发现上面的内容并不完全准确,因为有一个 302 指示用户登录,它访问了另一个没有静态资源的后端,因此上面的标题即将到来从登录后端。我将 URI 调整为仅指向图像,但没有发生缓存。我正在使用以下位置块:

  location /app/images {
    proxy_pass  http://cms-pool/app/images;
    proxy_cache cms-cache;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
    proxy_ignore_headers Cache-Control Expires Set-Cookie;
    proxy_hide_header Cache-Control;
    proxy_hide_header Set-Cookie;
  }

这些是现在通过的标题:

Accept-Ranges: bytes
Connection: keep-alive
Content-length: 12700
Content-Type: image/png
Date: Mon, 17 Nov 2014 09:25:38 GMT
ETag: "0cd80ce9afecf1:0"
HTTP/1.1 200 OK
Last-Modified: Wed, 12 Nov 2014 17:05:06 GMT
Server: nginx/1.7.6
Set-Cookie: AWSELB=4BB7AB49169E74EC05060FB9839BD30C2CB1D0E43D638163025E92245C6C6E40197CA48C5B22F3E8FDA53365109BC1C16C808322881855C100D4AC54E5C0EC6CDE91B96151F66369C7B697B04D2C08439274033D81;PATH=/
Set-Cookie: tscl-frontend=CgAK1FRpvxI4b0bQAwMEAg==; path=/
X-Powered-By: ASP.NET

【问题讨论】:

    标签: caching nginx amazon-elb


    【解决方案1】:

    这是由 ELB 背后的 HTTP 缓存标头的不稳定实现引起的。

    根据RFC 2616 (HTTP 1.1):

    Pragma 指令必须由代理或网关传递 应用程序,无论它们对该应用程序的重要性如何, 因为这些指令可能适用于沿线的所有接收者 请求/响应链。

    HTTP/1.1 缓存应该将“Pragma: no-cache”视为客户端拥有 发送“缓存控制:无缓存”。不会有新的 Pragma 指令 在 HTTP 中定义。

    注意:因为“Pragma: no-cache 作为响应”的意思 标题字段实际上没有指定,它不提供 响应中“Cache-Control: no-cache”的可靠替换

    Pragma: no-cache 标头在 HTTP 回复中没有任何意义,因为它的行为在 RFC 中未指定

    但由于 nginx 在您的情况下充当(反向)代理,它会将标头视为 Cache-Control: no-cache 标头,以保持与 RFC 1945 中定义的 HTTP 1.0 协议的 Pragma 标头的兼容性。

    它还将通过客户端的响应标头传递它,因为它不必假设它的实际含义。

    所以要么纠正这个错误的实现,要么将Pragma 标头附加到proxy_ignore_headersproxy_hide_header 指令。

    【讨论】:

    • 感谢您提供详细信息,我进行了一些挖掘并确定此标头是从另一个没有静态资源 (302) 的后端池发送的。我将 uri 调整为仅指向静态内容,但没有发生缓存,我会尽快更新问题的详细信息。
    • @Ashex 使用更新发布完整的 nginx 配置。 Set-Cookie 标头仍然存在于标头中,因此 nginx 可能没有使用您认为他所在的位置。
    • 我已经发布了完整的 nginx 配置,Set-Cookie 标头由 nginx 前面的 ELB 设置。一般架构如下:外部ELB - Nginx - 后端ELB - 应用服务器
    • @Ashex 好的。您的配置对我来说似乎没问题,您如何测试缓存是否被命中?
    • 我在 Incognito chrome 中加载页面,检查器打开并设置为不缓存。加载页面后,我检查 /usr/share/nginx/cache 下是否显示任何内容(检查缓存和应用程序),从 doc 开始,应该在那里创建一个临时文件/文件夹。
    猜你喜欢
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2021-02-15
    • 2021-03-19
    • 2016-12-10
    • 2016-02-15
    • 2017-06-10
    相关资源
    最近更新 更多