如果上游启动,则Nginx绕过缓存,如果关闭则使用缓存

问题描述 投票:1回答:2

要在上游启动时跳过缓存(max-age 1)并使用缓存if down(proxy_cache_use_stale)我创建了以下配置:

proxy_cache_path   /app/cache/ui levels=1:2 keys_zone=ui:10m max_size=1g inactive=30d;
server {
    ...
    location /app/ui/config.json {
        proxy_cache ui;
        proxy_cache_valid 1d;
        proxy_ignore_headers Expires;           
        proxy_hide_header Expires;
        proxy_hide_header Cache-Control;
        add_header Cache-Control "max-age=1, public";
        proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
        add_header X-Cache-Status $upstream_cache_status;
        add_header X-Cache-Date $upstream_http_date;
        proxy_pass http://app/config.json;
    }
}

但是,当上游关闭且客户端仅获得504网关超时时,不使用缓存。我已阅读以下文章:

https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_cache_use_stale

How to configure NginX to serve Cached Content only when Backend is down (5xx Resp. Codes)?

https://serverfault.com/questions/752838/nginx-use-proxy-cache-if-backend-is-down

而且它没有像我期望的那样工作。任何帮助表示赞赏。

nginx caching nginx-location nginx-reverse-proxy nginx-config
2个回答
2
投票

让我们讨论一个使用两台服务器的非常简单的设置。一个运行apache2服务于一个简单的HTML页面。另一个运行的nginx反向代理第一个。

http {
[...]

  proxy_cache_path /var/lib/nginx/tmp/proxy levels=2:2 keys_zone=one:10m inactive=48h max_size=16g use_temp_path=off;

  upstream backend {
    server foo.com;
  }

  server {
  [...]
    location / {
      proxy_cache           one;
      proxy_cache_valid     200 1s;
      proxy_cache_lock      on;

      proxy_connect_timeout 1s;
      proxy_cache_use_stale error timeout updating http_502 http_503 http_504;

      proxy_pass http://backend/
    }
  }
}

这个设置适合我。最重要的区别是proxy_cache_valid 200 1s;这意味着只有http代码200的响应才会被缓存,并且只有1秒有效。这意味着对某个资源的第一个请求将从后端获取并放入缓存中。对该相同资源的任何进一步请求将从缓存中提供一整秒。之后,第一个请求将再次发送到后端,等等。

proxy_cache_use_stale是您场景中的重要部分。它基本上说在哪些情况下它应该仍然服务于缓存版本,尽管proxy_cache_valid指定的时间已经过去了。所以在这里你必须决定你还想在哪些情况下从缓存中提供服务。

The directive's parameters are the same as for proxy_next_upstream.

你需要这些:

error:如果服务器仍然运行,但没有响应,或者没有正确响应。

timeout:连接到服务器,请求或响应超时。这也是你想将proxy_connect_timeout设置为低的原因。默认值为60秒,对于最终用户来说是很长的方式。

updating:已经有了新内容的请求。 (从性能的角度来看,并不是真正需要但更好。)

http_xxx参数对你来说不会有太大作用,当后端服务器关闭时,无论如何都不会得到任何这些代码的响应。

在我的现实生活中,后端服务器也是nginx,它代理localhost上的不同端口。因此,当nginx正常运行时,但是这些后端中的任何一个都没有参数http_502http_503http_504退出有用,因为这些正是我将收到的http代码。

http_403http_404http_500我不想从缓存中提供服务。当文件被禁止(403)或不再在后端(404)上或当脚本出错(500)时,有一个原因。但这是我的看法。


2
投票

与其他类似的问题一样,这就是XY Problem的例子。

用户想要做X,错误地认为解决方案是Y但不能做Y,所以请求帮助如何做Y而不是实际询问X.这总是会给那些试图给出答案的人带来问题。

在这种情况下,实际问题X似乎是您希望为后端进行故障转移,但希望避免在单独的服务器实例上花钱,并且想知道可用的选项。

为此使用缓存的想法并非完全关闭,但您必须像故障转移服务器那样接近并设置缓存,这意味着它必须是与后端完全独立且独立的系统。这排除了与后端密切相关的proxy_cache

在你的鞋子里,我将设置一个memcached服务器并配置它来缓存你的东西,但通常不会提供你的请求,除了50x错误。

有一个可以编译和使用的Nginx附带的memcached module,但它没有为memcached添加项目的工具。您必须在Nginx之外(通常在您的后端应用程序中)执行此操作。

设置memcached up can be found here或只是进行网络搜索的指南。一旦启动并运行,这将在Nginx方面为您工作:

server {
    location / {
        # You will need to add items to memcached yourself here
        proxy_pass             http://backend;
        proxy_intercept_errors on
        error_page             502 504 = @failover;
    }

    location @failover {
        # Assumes memcached is running on Port 11211
        set            $memcached_key "$uri?$args";
        memcached_pass host:11211;
    }
}      

远比有限的标准memcached模块更好的是来自OpenResty的3rd party memc module,它允许您直接在Nginx中添加内容。

OpenResty还具有非常灵活的lua-resty-memcached,这实际上是最佳选择。

对于这两种情况,您需要将它们编译到Nginx中并熟悉如何设置它们。如果您需要有关此方面的帮助,请在此处使用OpenResty标记询问新问题或尝试使用OpenResty支持系统。

Summary

  1. 您实际需要的是故障转移服务器。
  2. 这必须是独立于后端的,并且独立于后端。
  3. 您可以使用缓存系统,但它不能是proxy_cache如果你不能忍受在1秒的最短时间内获得缓存结果。
  4. 您需要扩展典型的Nginx安装才能执行此操作。
© www.soinside.com 2019 - 2024. All rights reserved.