我在与原始服务器相同的计算机上有一个Nginx反向代理。我希望代理从源缓存动态内容,但是当客户端重新验证资源时,我希望代理也可以使用源重新验证,而不是仅在不检查原点的情况下将304返回给客户端。
例如,如果我将max-age设置为60秒,代理将很快返回304,而不检查原点。我已经设置了一个测试,其中origin每秒生成一个新的etag,就像这样(使用node.js express):
app.get('/dynamic/:file?', function(req, res){
var filename = req.params.file;
var filepath = path.join(__dirname, 'files', filename);
res.setHeader('Cache-Control', 'public, must-revalidate, proxy-revalidate, max-age=60, s-maxage=60');
res.setHeader('ETag', filename+etagCounter);
res.sendfile(filepath);
console.log('request', requestCounter++);
console.log('etag', etagCounter);
console.log('date', new Date().toISOString());
});
在Nginx中,传递此请求的路由配置如下:
location /cache/ {
access_log on;
add_header Vary "Accept-Encoding";
add_header X-AppServer $upstream_addr; # Backend Server / Port
add_header X-AppServer-Status $upstream_status; # Backend HTTP Status
add_header X-Cache $upstream_cache_status; # HIT / MISS / BYPASS / EXPIRED
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_cache one;
proxy_cache_key $scheme$proxy_host$uri$is_args$args;
proxy_pass http://localhost:4444/;
}
当客户端直接与Express对话时,我看到Express返回了304,但是当Express之间存在代理时,Express永远不会返回304到Nginx。 Nginx从缓存服务,只在max-age过去时才从源文件中获取资源。
确保我将etag刷新间隔设置为60秒,将max-age设置为1.因此,Nginx将每秒从原点获取一个新资源(无需重新验证,因此需要200响应),然后将304返回给客户端,直到etag在60秒后发生变化。
我的结论是Nginx从未使用原始服务器重新验证。只要根据max-age认为它需要一个资源,它就会得到一个新的资源副本。
有没有办法做我想要的?它不尊重proxy-revalidate标头,还是我没有采取正确的方法?
[编辑]
我已经找到了答案here。从这篇文章中我构成了2个解决方案。
1)缓存响应中的必须重新验证/代理重新验证应足以让nginx在请求中接收max-age = 0时触发重新验证。
2)当客户端在CC头中发送'no-cache'时,代理应该肯定对源进行重新验证。
从我的测试来看,两者似乎都不起作用。例如,我正在做这样的请求:
curl 'http://localhost:9088/cache/dynamic/image.jpg' -H 'If-None-Match: image.jpg0' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Host: localhost:9088' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Cache-Control: no-cache, max-age=0' -H 'Cookie: octane.sid=s%3AUa64F6fk2Pw0uwZ28e7OICyv.z2FNPYjQ7%2Fn%2F3vZGXV7B3QBYtqN%2FHzjV1e3XTuZcnmwduE4SBFEPDv3zE3zRuA4Ae705RtI6Z%2BBrqJyMveSjNA' -H 'Connection: keep-alive' -H 'If-Modified-Since: Thu, 06 Sep 2012 09:21:53 GMT' --compressed -I
它包含-H 'Cache-Control: no-cache, max-age=0'
,但我仍然从nginx缓存中获取内容,而不检查原点。
Nginx在这方面表现不好吗?我使用的是1.5.4版本