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

时间:2018-09-05 16:21:52

标签: nginx caching nginx-location nginx-reverse-proxy nginx-config

要在上游启动时(最大年龄1)绕过高速缓存,而在下游启动时(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

而且它不符合我的预期。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:2)

与链接到的其他类似问题一样,这是XY Problem的示例。

一个用户想要做X,错误地认为解决方案是Y,但是不能做Y,因此寻求帮助如何做Y而不是实际询问X。这总是给那些试图给出答案的人带来麻烦。

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

为此目的使用缓存的想法还没有完全解决,但是您必须像故障转移服务器一样处理和设置缓存,这意味着它必须是与后端完全独立的系统。这排除了proxy_cache,后者与后端紧密相连。

在您的鞋子中,我将设置一个内存缓存服务器,并将其配置为缓存您的内容,但通常不会满足您的请求,除非出现50倍错误。

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

设置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;
    }
}      

OpenResty的3rd party memc module比受限制的标准memcached模块好得多,它允许您直接在Nginx中添加内容。

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

对于这两个实例,您都需要将它们编译到Nginx中,并熟悉如何设置它们。如果您需要帮助,请在此处使用OpenResty标签询问新问题,或尝试使用OpenResty支持系统。

摘要

  1. 您真正需要的是故障转移服务器。
  2. 这必须独立且独立于后端。
  3. 您可以这样使用缓存系统,但是如果您不能在至少1秒钟的时间内获得缓存结果,就不能使用proxy_cache
  4. 您将需要扩展典型的Nginx安装。

答案 1 :(得分: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,它代理本地主机上的不同端口。因此,当nginx运行正常时,但其中的任何后端均处于关闭状态,则参数http_502http_503http_504不再有用,因为这些正是我将收到的http代码。

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

答案 2 :(得分:0)

它不起作用,因为后端需要 http_500、http_502、http_503、http_504 代码。在您的情况下, 504 是 nginx 代码。 所以你需要具备以下条件:

function addToStore(objects) {
    Object.assign(store, objects); // Will do the loop and assignments for you
    return store;
}
// ...
addToStore({peach});
//         ^^^^^^^−−−−−−−−−−− creating the object to pass in using shorthand syntax

proxy_connect_timeout 10s;
proxy_cache_use_stale ... timeout ...

或两者兼而有之。