在 nginx 1.10.1 上,我代理一个外部网站(不受我控制)在本地缓存图像。
我的配置如下:
location ~ /cachedimages/(?<productcode>.*)/(?<size>.*)/image.jpg {
resolver 127.0.0.1;
proxy_pass https://www.externalsite.example/api/getImage/?productcode=$productcode&size=$size;
proxy_cache imgcache;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
expires 1M;
access_log off;
add_header 'Cache-Control' "public";
add_header Last-Modified $upstream_http_last_modified;
add_header X-Proxy-Cache $upstream_cache_status;
}
Run Code Online (Sandbox Code Playgroud)
imgcache
定义如下:
proxy_cache_path /var/cache/nginx/imgcache levels=1:2 keys_zone=imgcache:10m max_size=1g inactive=24h;
Run Code Online (Sandbox Code Playgroud)
远程服务器不提供Last-Modified
标题:
curl -X GET -I https://www.externalsite.example/api/getImage/?productcode=abc123&size=128
HTTP/1.1 200 OK
Date: Thu, 15 Sep 2016 08:16:07 GMT
Server: Apache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Run Code Online (Sandbox Code Playgroud)
我的服务器添加了一些标题但没有 Last-Modified
curl -X GET -I https://www.myserver.com/cachedimages/abc123/128/image.jpg
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 15 Sep 2016 08:33:26 GMT
Content-Type: image/jpeg
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Sat, 15 Oct 2016 08:33:26 GMT
Cache-Control: max-age=2592000
Cache-Control: public
X-Proxy-Cache: HIT
Run Code Online (Sandbox Code Playgroud)
如何强制 nginx 读取缓存(和命中)文件的 mtime 并将其用作Last-Modified
标头值?
所述$upstream_http_*
嵌入变量存储的头部信息通过在高速缓存中的上游服务器。您可以滥用Date:
上游发送的标头来填充反向代理发送的 Last-Modified 标头,如下所示:
add_header Last-Modified '$upstream_http_date';
Run Code Online (Sandbox Code Playgroud)
按预期工作:
Last-Modified: Sun, 22 Apr 2018 08:48:44 GMT
X-Cached: MISS
...
Last-Modified: Sun, 22 Apr 2018 08:50:05 GMT
X-Cached: HIT
...
Last-Modified: Sun, 22 Apr 2018 08:50:05 GMT
X-Cached: HIT
Run Code Online (Sandbox Code Playgroud)
有关 $upstream_http_* 的更多信息,请访问:http : //nginx.org/en/docs/http/ngx_http_upstream_module.html#variables(查找 $upstream_http_name)。
话虽如此,您试图实现 imho通常是一个坏主意:反向代理不知道上游对象自上次获取以来是否已更新,但它会告诉下游客户端该对象尚未更新被修改。这是虚假信息。
当然,可能有您想要这样做的原因,即如果您可以完全控制上游发生的任何对象更新和/或如果您计划每次需要手动刷新反向代理的缓存。
如果您只有一个反向代理,我强烈建议您将 ETags 视为解决问题的更好方法。如果您有一个反向代理池,则有效地使用 ETag 会变得复杂。
归档时间: |
|
查看次数: |
2328 次 |
最近记录: |