NGINX кэширующий вышестоящий сервер, когда это не должно быть - PullRequest
0 голосов
/ 15 января 2020

Я хочу настроить сервер NGINX, который обеспечивает следующие функциональные возможности:

  1. Когда делается запрос NGINX, чтобы получить страницу в / path / to / page, он выбирает страница в /path/to/page.
  2. Если вышестоящий сервер не работает или NGINX по какой-то причине не может к нему подключиться, NGINX возвращает кэшированную версию страницы, если она есть. .
  3. Если кешированный файл старше 6 часов, не используйте его, просто верните 502.
  4. Если сервер обратного потока доступен, никогда не использует кеш.

У меня есть конфигурация NGINX, которая, как мне кажется, должна работать на основе моего понимания документов, но это не так, и я не понимаю, почему. Проблема в пункте (4): этот NGINX сервер возвращает кэшированную версию файла, даже если вышестоящий сервер подключен к сети.

daemon off;
error_log /dev/stdout info;

events {
}

http {
    proxy_cache_path
        "/home/jack/Code/NGINX Caching/Codebase/cache"    # Cache path
        keys_zone=cache:10m # Name of cacahe, max size for keys 10 megabytes
        levels=1:2              # Don't store all cached files in a single directory
        max_size=500m           # Max size of cache
        inactive=6h;            # Cached file deleted if not used within six hours
    proxy_cache_valid 6h;
    proxy_cache_key "$request_method$request_uri";

    access_log /dev/stdout;

    server {
        listen 8080;

        location ~ ^/(.+)$ {
            proxy_pass http://0.0.0.0:8000/$1;
            proxy_cache cache;
            proxy_cache_valid 6h;
            proxy_buffering on;
            proxy_cache_use_stale error timeout;
        }
    }
}

Замените proxy_cache_path на путь к каталогу в на вашем компьютере и запустите другой веб-сервер на вашем компьютере через порт 8000. Когда я изменяю файл, обслуживаемый сервером на порту 8000, NGINX не видит изменения, пока я не удалю кэш. Проблема связана с NGINX, а не с моим клиентом (Firefox), даже если я отключаю кеширование в браузере, NGINX возвращает 200 со старым содержимым файла.

Ответы [ 2 ]

0 голосов
/ 16 января 2020

Итак, похоже, я неправильно понял директивы кэша прокси NGINX. Документы довольно запутанные по этому вопросу, поэтому я изложу их по пунктам.

На этой официальной справочной странице приведен приличный обзор различных директив, однако он не упоминает чего-то, что, как оказалось, является очень важным концептуальным строительным блоком в понимании того, как работает NGINX кэширование: понятие кэшированного файла устаревшее .

NGINX s default Поведение заключается в том, чтобы всегда использовать кеш, если он там есть, а не запрашивать вышестоящий сервер. С этой конфигурацией, минимальной конфигурацией для кэширования, NGINX будет запрашивать вышестоящий сервер при первом обращении к странице, а затем использовать кешированную версию навсегда:

events {
}

http {
    proxy_cache_path
        /path/to/cache
        keys_zone=my_cache:10m;
        proxy_cache_key "$request_method$request_uri";

    server {
        listen 8080;

        location ~ ^/(.+)$ {
            proxy_pass http://0.0.0.0:8000/$1;
            proxy_cache cache;
        }
    }
}

Вы можете использовать proxy_cache_valid директива, сообщающая NGINX, когда кэшированный файл следует считать "устаревшим". Например, если мы установим proxy_cache_valid 5m, то через 5 минут после создания файла кэша NGINX прекратит его обслуживание и снова запросит вышестоящий сервер при следующем запросе. Если восходящий поток не работает, NGINX вернет 502. Однако в течение этих пяти минут NGINX будет по-прежнему использовать кеш, даже если сервер обратного потока доступен, так что это не то, что нам нужно.

NGINX имеет другую директиву proxy_cache_use_stale, которая дает NGINX условия, при которых он может использовать кэшированные файлы , даже если они устарели. Мы можем объединить их вместе, чтобы получить сервер, который кэширует страницы, делает их устаревшими сразу (или почти сразу), а затем использует их, только если восходящий поток не работает:

events {
}

http {
    proxy_cache_path
        /path/to/cache
        keys_zone=my_cache:10m;
        proxy_cache_key "$request_method$request_uri";

    server {
        listen 8080;

        location ~ ^/(.+)$ {
            proxy_pass http://0.0.0.0:8000/$1;
            proxy_cache cache;
            proxy_cache_valid 1s;
            proxy_cache_use_stale error timeout;
        }
    }
}

Эта конфигурация почти соответствует поведению, которое мы хочу, за исключением того, что если вышестоящий сервер отключается в течение продолжительного периода времени, NGINX будет продолжать использовать кэш бесконечно. Насколько я знаю, нет способа сказать NGINX полностью аннулировать / очистить кешированный файл через заданный промежуток времени. Обычно это то, для чего proxy_cache_valid, но мы уже используем это для другой цели, чтобы сделать файлы устаревшими через 1 секунду, чтобы они только использовались, когда восходящий поток не работает. Нам понадобится следующий уровень после «устаревшего», что означает, что файл полностью признан недействительным, но я не думаю, что он существует в NGINX.

Так что самое простое решение - просто очистить кэш вручную. Достаточно просто удалить все файлы в каталоге кэша (или его подкаталогах), которые в последний раз модифицировались более 6 часов go, или любое другое время истечения срока действия. В системе Linux этот сценарий можно запускать каждые 5 минут, например:

find /path/to/cache -type f -mmin +360 -delete
0 голосов
/ 15 января 2020

Не могли бы вы проверить, могут ли эти две директивы помочь вам:

proxy_cache_revalidate: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_revalidate

и

proxy_cache_use_stale: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_use_stale

На сайте nginx .conf '17 есть видео, описывающее все классные вещи, которые вы можете достичь с помощью кэширования: https://www.youtube.com/watch?v=xZrOjmAkFC8. может быть, это также вас интересует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...