【问题标题】:nginx caching: return cached page (when specific Cache-Control header given) only if the upstream server is not reachablenginx 缓存:仅当上游服务器不可访问时才返回缓存页面(当给出特定的 Cache-Control 标头时)
【发布时间】:2020-02-23 20:22:30
【问题描述】:

我正在尝试为上游服务器(我不管理)设置缓存。大多数文件都可以缓存(并且没有设置Cache-Control),这些都可以正常工作。

但是,服务器上的某些位置是目录列表(并且有Cache-Control: no-store)。我只想在服务器无法访问时缓存它们。 不幸的是,我最终会出现以下情况之一:

  • 在没有缓存这些列表的情况下(缓存中没有文件,标题总是显示缓存未命中)。如果服务器无法访问,则(显然)不会返回目录列表
  • 在这些列表被缓存但之后永远不会更新的情况下(至少在缓存有效时不会更新)。由于我想长时间缓存所有其他条目,因此目录列表很快就会过时。

我尝试将标题修改为stale-if-error,但这似乎也没有帮助。

map $http_cache_control $http_updated_cache_control {
  no-store stale-if-error;
}

server {
...
  location /somewhere {
      sendfile on;
      sendfile_max_chunk 10m;
      tcp_nopush on;
      proxy_cache keyzone;

      # allow using stale requests in case of errors or when updating a file
      proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
      proxy_cache_revalidate on;
      proxy_cache_background_update on;

      # add header to indicate if caching works
      add_header X-Cache-Status $upstream_cache_status;

      proxy_cache_lock on;
      proxy_read_timeout  900;
      proxy_pass_header   Server;
      proxy_ignore_headers Set-Cookie;

      # allow caching of non-cacheable entries only when the server is erroring
      proxy_hide_header Cache-Control;
      add_header Cache-Control $http_updated_cache_control;

      # don't ignore the cache control header: some items (like directory listings) are marked as "don't cache")
      #proxy_ignore_headers Cache-Control;
  }
}

如何使用Cache-Control: no-store 缓存条目,但仅在上游服务器关闭时才使用缓存的条目?

【问题讨论】:

  • 添加上游服务器和代理的响应头。 “(至少只要缓存有效)”是什么意思? Cache-Control: no-store内容的缓存有效性如何定义?
  • 我的意思是:如果我将proxy_cache_valid设置为一个很大的值(最好是几天),我想要缓存的东西会被缓存很长时间。不幸的是,这意味着我只想在出现错误时缓存的项目也被缓存(和使用)10 天。如果我把它设置为一个非常短的值,那么我要缓存的项目也不会缓存很长。

标签: nginx caching


【解决方案1】:

我看到了两种可能性:

  1. NGINX 尊重来自上游服务器的标头。因此,如果上游发送Expires,尽管Cache-Control: no-store,那么在您修改NGINX的标头后,它们将变为Expires: ... Cache-Control: stale-if-error并等待

    至少只要缓存有效

  2. proxy_cache_valid大概也有同样的效果

所以你需要

  1. 要么为proxy_cache_valid 设置一些小的值,要么为location /somewhere
  2. 或/和删除Expires(如果存在)
  3. 或/和将max-age=0 添加到Cache-Control

【讨论】:

  • 谢谢!我现在为 proxy_cache_valid 配置了一个小值(10 秒)。由于我已将 proxy_cache_use_stale 设置为在“更新”时返回,这意味着我至少会收到一次过时的响应(例如,如果我执行 1 个请求,等待一个小时再执行第二个,第二个请求将非常旧)。但是,如果我省略“更新”,则意味着它将重新验证,所以我也做了那个小改动。现在它的行为应该如此!谢谢! :-)
猜你喜欢
  • 2017-03-23
  • 2019-12-03
  • 2020-05-02
  • 2018-12-10
  • 2022-12-15
  • 2016-08-14
  • 2018-02-22
  • 2021-10-18
  • 2018-07-10
相关资源
最近更新 更多