代码之家  ›  专栏  ›  技术社区  ›  Anatoli

Nginx在上行时绕过缓存,在下行时使用缓存

  •  1
  • Anatoli  · 技术社区  · 6 年前

    要在上游打开时绕过缓存(最大年龄1)并在关闭时使用缓存(代理\缓存\使用\过时),我创建了以下配置:

    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

    但它并不像我预期的那样有效。感谢您的帮助。

    2 回复  |  直到 6 年前
        1
  •  5
  •   RemyNL    6 年前

    让我们来讨论一个非常简单的两台服务器的设置。一个运行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;

    这个 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 参数不会对您有多大帮助,当后端服务器关闭时,您无论如何都不会得到这些代码的响应。

    http_502 , http_503 http_504

    这个 http_403 , http_404 http_500 我不想在储藏室服侍。当文件被禁止(403)或不再在后端(404)或脚本出错(500)时,这是有原因的。但这是我的看法。

        2
  •  2
  •   Dayo    6 年前

    这和其他与之相关的类似问题一样,都是 XY Problem .

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

    在本例中,实际的问题X似乎是您希望为后端进行故障切换,但希望避免在单独的服务器实例上花钱,并且希望知道有哪些可用的选项。

    使用缓存的想法并不是完全关闭的,但是您必须像故障转移服务器一样接近和设置缓存,这意味着它必须是一个与后端完全独立的系统。这就排除了 proxy_cache 它与后端紧密相连。

    在你的鞋子,我会设置一个memcached服务器,并配置这个缓存你的东西,但通常不服务于你的请求,除非在一个50倍的错误。

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

    memcached设置指南 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模块好得多的是 3rd party memc module

    lua-resty-memcached

    对于这两种情况,您都需要将它们编译到Nginx中,并熟悉如何设置它们。如果您需要这方面的帮助,可以在这里用OpenResty标签问一个新问题,或者试试OpenResty支持系统。

    1. 您实际上需要的是一个故障转移服务器。
    2. 这必须独立于后端。
    3. 您可以这样使用缓存系统,但不能这样 代理缓存 如果您不能忍受在最短1秒的时间内获取缓存结果。
    4. 为此,您需要扩展一个典型的Nginx安装。