Nginx不缓存通过ELB发出的请求



我有nginx坐在ELB之间。我在 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/elb 前面):

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

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

根据 RFC 2616 (HTTP 1.1):

杂注指令必须由代理或网关传递应用程序,无论它们对该应用程序的重要性如何,由于该指令可能适用于沿请求/响应链。

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

注意:因为"杂注"的含义:无缓存作为响应标题字段实际上没有指定,它没有提供响应中"缓存控制:无缓存"的可靠替代

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

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

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

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

最新更新