我在应用服务器前面使用 nginx 作为反向代理。应用程序使用 X-Accel-Redirect 标头进行响应,告诉 nginx 要提供哪个静态文件。我希望能够让 nginx 缓存其中一些上游响应,以便它可以提供正确的文件而无需访问应用服务器。
不幸的是,这不起作用:nginx 似乎拒绝缓存任何带有 X-Accel-Redirect 标头的响应。如果我不使用 X-Accel-Redirect 并让应用服务器返回文件本身,那么缓存就可以完美地工作。然而,这并不是很有效,因为应用服务器必须从磁盘读取文件并将其发送到 nginx,然后 nginx 将文件写回磁盘(在其缓存中)并将其发送到客户端。
以下是我的 nginx 配置的精简版本:
proxy_cache_path /tmp/nginx-cache keys_zone=testzone:10m;
server {
location / {
proxy_cache testzone;
proxy_pass http://localhost:8000/;
}
location /static-files/ {
internal;
alias /var/static-files/;
}
}
有人知道我尝试做的事情是否可行吗?我怀疑当 nginx 发现 X-Accel-Redirect 标头时,它会立即跳转到处理提供的 URI 并跳过正常的缓存逻辑,但如果能确认这一点就好了。
答案1
我遇到过类似的情况,nginx 不想缓存我的东西,因为我正在使用的 web 应用程序试图设置我不想设置的 cookie。
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers
除非您想雇人来破解源代码,否则您可以尝试让 nginx 作为其自身的代理,然后再作为 Web 应用程序的代理。
对于中间的那个,您可以忽略X-Accel-Redirect
标题,因此缓存应该再次启动。
对于前端的那个,您不进行缓存,而是将请求代理到中间缓存X-Accel-Redirect
响应的那个。
我不明白为什么这样的事情不起作用!:-)
答案2
我建议您重写您的服务器和位置块:
server {
location / {
proxy_cache testzone;
proxy_pass http://localhost:8000;
}
location ~* \.(ico|js|jpg|png|gif|jpeg|mp3|wav|swf|mov|doc|pdf|flv|css)$ {
expires max;
proxy_cache testzone;
proxy_pass http://localhost:8000;
}
}
还要查看 proxy_temp_pathhttp://wiki.nginx.org/HttpProxyModule#proxy_temp_path。尽管默认情况下已经启用(我认为),但我喜欢查看此文件夹以查看是否存储了对静态内容的请求。