我看到有迹象表明这应该有效,所以我希望我遗漏了一些简单的东西。
我们有两个 nginx“服务器”,一个是前面的 proxy_pass 缓存,一个是后面的 SSI 服务器。如果我直接使用请求中的 If-Modified-Since 标头访问 SSI 服务器,它将返回 304-Not Modified 响应,这正是我们想要的。但我无法让 proxy_pass 缓存服务器对任何内容返回 304-Not Modified。
应该我能让 proxy_pass 返回 304-Not Modified 吗?有没有其他人能用你分享的配置来使用它?或者你能发现我的配置中存在问题吗?
# this is the cache in front
server {
listen 8096;
server_name _;
proxy_buffering on;
location /assets {
proxy_pass http://localhost:8095;
proxy_cache my-cache;
proxy_cache_valid 200s;
if_modified_since before;
}
}
server {
listen 8095;
server_name _;
root /var/www/;
location / { deny all; }
location /assets {}
ssi on; # on or off doesn't make a difference to the front-end cache behavior
if_modified_since before;
}
}
# here's the base config, fwiw:
proxy_buffering on;
proxy_cache_valid any 10m;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my-cache:8m max_size=3000m inactive=24h;
proxy_temp_path /var/cache/nginx/tmp;
proxy_buffer_size 4k;
proxy_buffers 100 8k;
谢谢。
答案1
问题是,if-modified-since
当缓存生效时,nginx 不会将缓存从客户端传递到上游服务器(我相信这取决于是否存在设置 )。根据我的调查 [1],proxy_cache
Nginx 会删除缓存。if-modified-since header
解决方案是添加proxy_set_header If-Modified-Since $http_if_modified_since
到前端 [2]。幸运的是,nginx 并没有试图在这里表现得太聪明...它忠实地将请求中的标头复制到上游,这正是我们想要的。
如果我们只是缓存静态文件,那么默认的 Nginx 行为是有意义的,但如果应用服务器需要做出更复杂的决定来决定是否重新生成内容,我们就需要将其传递下去!
如果有人想调查这个问题,我发现这是通过
$http_if_modified_since
在前端服务器和上游服务器上添加 nginx 访问日志格式来实现的。对于给定的请求,前端服务器记录了if-modified-since
客户端发送的标头,但相同的请求被记录为一个空的 if-modified-since 标头,直到我应用修复程序proxy_set_header
。正如 Andrew Ty 在这个问题的评论中所提到的。
答案2
是的,这是可能的,而且这个配置确实可以正常工作。事实证明,根据我的测试,nginx 缓存了一个设置为下周的 Expires 标头。 没关系:-/
答案3
解决方案是添加proxy_cache_revalidate on
。如果启用了缓存,NGINX 默认不会在对上游服务器的请求中包含 If-Modified-Since 和其他条件请求标头。它需要此指令来指示在资源过期时向上游服务器发出条件请求。
资源: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_revalidate