Nginx обходной кеш, если upstream работает, и использовать кеш, если down - PullRequest
0 голосов
/ 05 сентября 2018

Чтобы обойти кеш, если upstream работает (max-age 1), и использовать кеш, если 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 Gateway Timeout. Я уже прочитал следующие статьи:

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

Как настроить NginX для обслуживания кэшированного содержимого только при неработающем бэкэнде (5xx Resp. Codes)?

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

И это не работает, как я ожидаю. Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Давайте обсудим очень простую настройку с двумя серверами. Один работает 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, уже прошло. Итак, здесь вы должны решить, в каких случаях вы все еще хотите обслуживать из кэша.

Параметры директивы такие же, как для proxy_next_upstream.

Вам понадобятся эти:

error: если сервер все еще работает, но не отвечает или не отвечает правильно.

timeout: подключение к серверу, время ожидания запроса или ответа. Это также, почему вы хотите установить proxy_connect_timeout на что-то низкое. По умолчанию установлено значение 60 с, а для конечного пользователя - длинное.

updating: уже есть запрос на новый контент. (не очень нужно, но лучше с точки зрения производительности.)

Параметры http_xxx не принесут вам большой пользы, когда этот сервер не работает, вы никогда не получите ответ ни с одним из этих кодов.

В моем случае с реальной жизнью внутренний сервер также является nginx, который проксирует разные порты на локальном хосте. Поэтому, когда nginx работает нормально, но любой из этих бэкэндов не работает, параметры http_502, http_503 и http_504 оказываются бесполезными, поскольку именно эти http-коды я получу.

http_403, http_404 и http_500 Я бы не хотел обслуживать из кеша. Когда файл запрещен (403) или отсутствует в бэкэнде (404) или когда скрипт работает неправильно (500), есть причина для этого. Но это мое мнение.

0 голосов
/ 08 сентября 2018

Это, как и другие похожие вопросы, связанные с, являются примерами проблемы XY .

Пользователь хочет сделать X, ошибочно полагает, что решение - это Y, но не может сделать Y, и поэтому просит помощи о том, как сделать Y, вместо того, чтобы фактически спрашивать о X. Это неизменно приводит к проблемам для тех, кто пытается дать ответ.

В этом случае реальная проблема, X, заключается в том, что вы хотели бы иметь отказоустойчивость для своего бэкэнда, но хотели бы не тратить деньги на отдельный экземпляр сервера и хотели бы знать, какие варианты доступны.

Идея использования кеша для этого не совсем отключена, но вы должны подойти и настроить кеш как отказоустойчивый сервер, что означает, что это должна быть совершенно отдельная и независимая система от бэкэнда. Это исключает proxy_cache, который тесно связан с бэкэндом.

На вашем месте я настрою сервер memcached и сконфигурирую его для кэширования ваших материалов, но не для обычной обработки ваших запросов, за исключением ошибки 50x.

Существует модуль memcached , который поставляется с Nginx, который можно скомпилировать и использовать, но у него нет возможности добавлять элементы в memcached. Вам придется делать это вне Nginx (обычно в вашем бэкэнд-приложении).

Руководство по настройке memcached up можно найти здесь или просто выполнить поиск в Интернете. Как только он будет запущен, он будет работать для вас на стороне 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, это сторонний модуль memc от OpenResty, который позволяет добавлять вещи непосредственно в Nginx.

OpenResty также имеет очень гибкий lua-resty-memcached , который на самом деле является лучшим вариантом.

В обоих случаях вам нужно будет скомпилировать их в свой Nginx и ознакомиться с тем, как их настроить. Если вам нужна помощь в этом, задайте новый вопрос здесь с тегом OpenResty или попробуйте систему поддержки OpenResty.

Резюме

  1. Что вам действительно нужно, так это отказоустойчивый сервер.
  2. Он должен быть отдельным и независимым от серверной части.
  3. Вы можете использовать систему кэширования в качестве этой, но это не может быть proxy_cache, если вы не можете жить с получением кэшированных результатов в течение минимального времени 1 секунды.
  4. Для этого вам потребуется расширить типичную установку Nginx.
...