Proxycache ошибка загрузки кэша прокси сервера

Исходный адрес:https://blog.csdn.net/dengjiexian123/article/details/53386586/

Предисловие:

Благодаря своей работе я занимаюсь вебкастингом, в котором для воспроизведения и загрузки видео используются некоторые технологии загрузки видео. Текущий основной подход на рынке для загрузки полного видео заключается в том, чтобы сначала нарезать весь видеопоток и сохранить его на файловом сервере, когда пользователю необходимо просмотреть воспроизводимое видео. Передайте видео обратно на исходный сервер, перейдите на файловый сервер, чтобы запросить фрагменты один за другим и вернуть их пользователю для воспроизведения.

Сегодня я сосредоточусь на настройке кэширования обратного сервера и разумных стратегиях кэширования.

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

Сегодняшнее объяснение разделено на четыре пункта:

  • Какова работа сервера возврата к источнику
  • Зачем нужно добавлять кеширование на исходный сервер
  • Как настроить кеш
  • Как настроить полный механизм кеширования для бизнес-сценариев

Работа back-to-origin сервера:

Сервер обратного происхождения упоминается как исходная станция в следующем описании.

Как показано на рисунке, в процессе загрузки файла он проходит между CDN и файловым сервером в качестве концентратора загрузки.

Архитектура исходного сайта: исходный сайт — это архитектура веб-сервера nginx + php, как показано на рисунке:

Но если исходный сайт просто получает запрос, загружает ресурс и затем возвращается, обязательно возникнут следующие проблемы, которые не будут оптимизированы:

1. CDN может иметь многократное возвращение к источнику.

2. Множественные загрузки одного и того же ресурса исходным сайтом приведут к потере полосы пропускания сетевого трафика и ненужным затратам времени.

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

Принцип proxy_cache:

Принцип работы модуля proxy_cache показан на рисунке:

Как настроить модуль proxy_cache

Добавьте следующий код в файл nginx.conf:

 
  1. http{

  2. ......

  3. proxy_cache_path/data/nginx/tmp-test levels=1:2 keys_zone=tmp-test:100m inactive=7d max_size=1000g;

  4. }

Описание кода:

proxy_cache_path Путь к кеш-файлу

Уровни Устанавливает уровень каталога файлов кэша; уровни = 1: 2 указывает на два уровня каталога.

keys_zone Установить имя кеша и размер разделяемой памяти

неактивно Удаляется, если никто не посещает в течение указанного времени

max_size Максимальное пространство кэша. Если пространство кэша заполнено, ресурс с наибольшим временем кеширования будет перезаписан по умолчанию.

После завершения настройки перезапустите nginx, если об ошибках не сообщается, настроенный proxy_cache вступит в силу

Проверьте каталог proxy_cache_path / data / nginx /,

Вы обнаружите, что создана папка tmp-test.

Как использовать proxy_cache

Добавьте следующий код в соответствующий файл конфигурации сервера nginx vhost:

 
  1. location /tmp-test/ {

  2. proxy_cache tmp-test;

  3. proxy_cache_valid 200 206 304 301 302 10d;

  4. proxy_cache_key $uri;

  5. proxy_set_header Host $host:$server_port;

  6. proxy_set_header X-Real-IP $remote_addr;

  7. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  8. proxy_passhttp://127.0.0.1:8081/media_store.php/tmp-test/;

  9. }

Введение в элемент конфигурации:

Proxy_cache tmp-test использует соответствующую конфигурацию кеша с именем tmp-test

proxy_cache_valid 200 206 304 301 302 10d; кеш на 10 дней для httpcode 200 …

proxy_cache_key $ uri Определяет уникальный ключ кеша и обращается к хешу через уникальный ключ

proxy_set_header Пользовательский заголовок HTTP-заголовка, используемый для отправки на внутренний реальный сервер.

proxy_pass относится к пути пересылки после прокси, обратите внимание, является ли последний /

На этом этапе самая основная функция proxy_cache успешно настроена. Когда uri успешно совпадает с местоположением, proxy_cache вступит в силу.

После добавления proxy_cache изменения в процессе запроса:

1. Первое посещение:

При первом посещении proxy_cache не нашел соответствующий файл кеша (отсутствует кеш MISS), поэтому при выполнении первого запроса proxy_cache сохранит кеш:

2. Сохраните кеш, как показано на рисунке:

3. При повторном обращении к тому же URL-адресу, когда тот же файл снова поступает на исходный сайт, proxy_cache найдет соответствующий ему файл кеша (ударит HIT кеша) и вернет его непосредственно запрашивающей стороне без выполнения программы PHP, как показано на рисунке:

Задайте вопрос:

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

  1. Необходимо активно очищать файлы кеша
  2. Путь записи — диск. Что делать, если диск заполнен?
  3. Как сделать так, чтобы исходный сайт поддерживал возобновляемую передачу и стратегию кэширования возобновляемой передачи
  4. Если запрашивающая сторона запрашивает запрос диапазона (сегментированная загрузка) для большого ресурса и того же URI, как отличить запрос?
  5. Вам также необходимо сообщить запрашивающей стороне время истечения срока действия ресурса.
  6. Журнал статистики, как настроить поля попаданий и промахов и как вести статистику?

Столкнувшись с вышеуказанными вопросами, мы решаем их по очереди.

Вопрос 1: заранее очистите кеш

Принять: модуль nginx proxy_cache_purge, который появляется в паре с proxy_cache, а функция как раз наоборот.

Метод разработки: в nginx запустите другой сервер и, когда вам нужно очистить кеш ресурсов ответа, обратитесь к этому серверу на локальном компьютере.

Например:

Посетите 127.0.0.1:8083/tmp-test/TL39ef7ea6d8e8d48e87a30c43b8f75e30.txt, чтобы очистить файл кеша этого ресурса.

Метод конфигурации:

 
  1. location /tmp-test/ {

  2. allow 127.0.0.1; // Разрешить только локальный доступ

  3. deny all; // Запрещаем все остальные ip

  4. proxy_cache_purge tmp-test $ uri; // Очистить кеш

  5. }

proxy_cache_purge: модуль очистки кеша

tmp-test: указанная key_zone

$ uri: указанные параметры для генерации ключа

Процесс очистки кеша proxy_cache_purge, как показано на рисунке:


 

Вопрос 2: Что делать, если кеш-файл заполнен диском?

Поскольку путь записи — это один каталог, можно записать только один диск. Диск скоро заполнится. Есть два способа решить эту проблему:

1. Будет ли несколько дисков использоваться как дисковый массив? Недостатком является то, что фактическое пространство для хранения уменьшается.

2. Используйте структуру каталогов proxy_cache_path с умом. Поскольку уровни = 1: 2, это приводит к двухуровневой структуре каталогов для файла кэша, а имя каталога каждого уровня генерируется хеш-функцией. как показано на картинке:

Всего имеется 16 * 16 * 16 = 4096 файловых каталогов. Создайте мягкую ссылку на каталог первого уровня и, соответственно, мягкую ссылку 0-f на указанный каталог диска, который вам нужен, как показано на рисунке:

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

Вопрос 3: Диапазон поддержки (возобновление точки останова)

После добавления прокси-сервера кеша запрос диапазона, инициированный клиентом, станет недействительным, как показано на следующем рисунке:

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

Когда прокси-сервер кеша пересылает http-запрос на внутренний сервер, заголовок http изменится, и некоторые параметры в заголовке будут отменены. Среди них был отменен параметр диапазона, в результате чего внутренний сервер nginx не получил параметр диапазона, что в итоге привело к неудачной загрузке этого сегмента. Итак, вам нужно настроить заголовок, пересылаемый прокси.

Например:

 
  1. location /tmp-test/ {

  2. proxy_cache tmp-test;

  3. proxy_cache_valid 200 206 304 301 302 10d;

  4. proxy_cache_key $uri;

  5. <span style="color:#ff0000;">proxy_set_header Range $http_range;</span>

  6. proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/;

  7. }

Значение красной части: поместите значение диапазона ($ http_range) в HTTP-запросе в заголовок HTTP-запроса, пересылаемый прокси-сервером в качестве значения диапазона параметров.

Вопрос четвертый, после поддержки загрузки диапазона необходимо перенастроить proxy_cache_key:

Если запрашивающий диапазон запрашивает (фрагментированную загрузку) большой ресурс, тот же uri, как кеш прокси определяет ключ, соответствующий ресурсу?

Поскольку nginx настроен как proxy_cache_key $ uri, используйте uri в качестве ключа

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

Решение такое:

Измените proxy_cache_key, настройте proxy_cache_key $ http_range $ uri;

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

Вопрос 5: Как настроить-вернуть срок годности

Необходимо указать инициатора запроса, вернув время истечения срока действия, какие ресурсы необходимо кэшировать, а какие не кэшируются,

параметр Нормальный запрос запрос диапазона
Срок годности возврата возвращаться Не возвращайся

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

Чтобы решить эту проблему, ее можно решить, настроив nginx:

 
  1. location /media_store.php {

  2. fastcgi_pass 127.0.0.1:9000;

  3. fastcgi_index media_store.php;

  4. fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

  5. include fastcgi_params;

  6. if ( $http_range = ''){

  7. expires 2592000s;

  8. }

  9. }

Добавьте оценку $ http_range к местоположению после proxy_pass, и expires представляет время истечения срока. 2592000 с — время истечения срока действия кеша.

Вопрос 7: Как отразить попадания в кеш в заголовке http и просмотреть его в журнале nginx

Решение:

Используйте переменную nginx $ upstream_cache_status: эта переменная представляет состояние попаданий в кеш,

При попадании — УДАРЕ; при промахе — ПРОПУСТИТЬ.

Добавьте в возвращаемую конфигурацию сервера nginx:

add_header  Nginx-Cache «$upstream_cache_status»;

Добавьте в nginxlog:

log_format       combinedio  …$upstream_cache_status;

http return head скриншот:

Снимок экрана журнала nginx:

подводить итоги:

Здесь представлен полный набор полных стратегий кэширования.Этот набор решений не только реализует базовую конфигурацию кеша, но также решает проблемы, возникающие в реальных приложениях сцены, такие как расширение диска, очистка кеша, возобновляемая загрузка и время истечения срока действия кеша. , Кэшируйте подсказки о попаданиях и другие проблемы, пока этот набор решений используется гибко, независимо от того, насколько сложна сцена, он в основном может удовлетворить потребности. Выше перечислены все ямы, через которые я пролез в своей работе, и результаты, обобщенные путем постоянного улучшения, я надеюсь, что это будет полезно для читателей.

This library use one HttpProxyCacheServerClients for same url ,for every single request,the HttpProxyCacheServer start a new thread to handle the request,so there would be more than one thread running with HttpProxyCacheServerClients.processRequest().
For partial request,it will go like this:
HttpProxyCacheServerClients.processRequest()->
HttpProxyCache.processRequest()->
HttpProxyCache.responseWithoutCache(),
here is the code of «responseWithoutCache()» method:

private void responseWithoutCache(OutputStream out, long offset) throws ProxyCacheException, IOException {
    try {
        HttpUrlSource source = new HttpUrlSource(this.source);
        source.open((int) offset);
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int readBytes;
        while ((readBytes = source.read(buffer)) != -1) {
            out.write(buffer, 0, readBytes);
            offset += readBytes;
        }
        out.flush();
    } finally {
       //this is where the bug happens,the source might being used in ProxyCache.readSource()**
       //if there is a another request running with HttpProxyCache.responseWithCache()**
       source.close();
    }
}

At the finally block,the «source.close()» will close the source might being used in ProxyCache.readSource() if there is a another request running with HttpProxyCache.responseWithCache(),so the cache thread will stop,then the MediaPlayer will get no data return.
I think what the author really want to do is to close the source in the try block.

PS:The log when the MediaPlayer stop work:

12-26 13:09:48.469 1759-1759/? I/ProxyCache: Proxy cache server started. Ping it...
12-26 13:09:48.479 1759-1800/? D/ProxyCache: Open connection  to http://127.0.0.1:37550/ping
12-26 13:09:48.479 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=33754,localPort=37550]
12-26 13:09:48.479 1759-1801/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=0, partial=false, uri='ping'}
12-26 13:09:48.479 1759-1801/? D/ProxyCache: Opened connections: 0
12-26 13:09:48.489 1759-1800/? D/ProxyCache: Ping response: `ping ok`, pinged? true
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52510,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52511,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52512,localPort=37550]
12-26 13:09:48.649 1759-1799/? D/ProxyCache: Accept new socket Socket[address=/127.0.0.1,port=52513,localPort=37550]
12-26 13:09:48.649 1759-1806/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=0, partial=false, uri='http://video_url'}
12-26 13:09:48.679 1759-1806/? D/ProxyCache: Read content info from http://video_url
12-26 13:09:48.679 1759-1806/? D/ProxyCache: Open connection  to http://video_url
12-26 13:09:49.329 1759-1806/? I/ProxyCache: Content info for `http://video_url`: mime: video/mp4, content-length: 24051189
12-26 13:09:49.329 1759-1811/? D/ProxyCache: Open connection  to http://video_url
12-26 13:09:50.299 1759-1807/? I/ProxyCache: Request to cache proxy:GetRequest{rangeOffset=23737472, partial=true, uri='http://video_url'}
12-26 13:09:50.299 1759-1807/? D/ProxyCache: Open connection  with offset 23737472 to http://video_url
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Closing socket… Socket is closed by client.
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Releasing input stream… Socket is closed by client.
12-26 13:09:50.329 1759-1806/? D/ProxyCache: Opened connections: 1
12-26 13:09:51.969 1759-1807/? D/ProxyCache: Shutdown proxy for HttpUrlSource{url='http://video_url}
12-26 13:09:51.979 1759-1811/? E/ProxyCache: ProxyCache error
                                             com.danikula.videocache.ProxyCacheException: Error reading data from http://video_url
                                                 at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:99)
                                                 at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126)
                                                 at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19)
                                                 at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179)
                                                 at java.lang.Thread.run(Thread.java:856)
                                              Caused by: java.net.SocketException: Socket closed
                                                 at libcore.io.Posix.recvfromBytes(Native Method)
                                                 at libcore.io.Posix.recvfrom(Posix.java:131)
                                                 at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
                                                 at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
                                                 at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
                                                 at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
                                                 at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
                                                 at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
                                                 at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
                                                 at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
                                                 at com.danikula.videocache.HttpUrlSource.read(HttpUrlSource.java:95)
                                                 at com.danikula.videocache.ProxyCache.readSource(ProxyCache.java:126) 
                                                 at com.danikula.videocache.ProxyCache.access$100(ProxyCache.java:19) 
                                                 at com.danikula.videocache.ProxyCache$SourceReaderRunnable.run(ProxyCache.java:179) 
                                                 at java.lang.Thread.run(Thread.java:856) 
12-26 13:09:51.979 1759-1807/? D/ProxyCache: Opened connections: 0
12-26 13:09:58.659 1759-1808/? D/ProxyCache: Opened connections: 0
12-26 13:09:58.669 1759-1809/? D/ProxyCache: Opened connections: 0

PPS:I replaced the video url in the log.

Я пытаюсь кэшировать статический контент, который в основном находится внутри путей ниже в конфигурации виртуального сервера. По какой-то причине файлы не кэшируются. Я вижу несколько папок и файлов внутри кэша dir, но его всегда что-то вроде 20mb не выше, не ниже. Если бы это было кэширование изображений, например, заняло бы не менее 500 МБ пространства.

вот nginx.часть кэша conf:

** nginx.conf **
proxy_cache_path /usr/share/nginx/www/cache levels=1:2 keys_zone=static$
proxy_temp_path /usr/share/nginx/www/tmp;
proxy_read_timeout 300s;

вот виртуальный сервер по умолчанию.

**sites-available/default**
server {
    listen   80; 

    root /usr/share/nginx/www;
    server_name myserver;
    access_log /var/log/nginx/myserver.log main;
    error_log /var/log/nginx/error.log;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location ~* ^/(thumbs|images|css|js|pubimg)/(.*)$ {
            proxy_pass http://backend;
            proxy_cache static;
            proxy_cache_min_uses 1;
            proxy_cache_valid 200 301 302 120m;
            proxy_cache_valid 404 1m;
            expires max;
    }

    location / {
            proxy_pass http://backend;
    }
}

4 ответов


убедитесь, что ваш сервер не возвращает Set-Cookie заголовок. Если Nginx видит его, он отключает кэширование.

если это ваш случай, лучшим вариантом является исправление вашего бэкэнда. Когда исправление бэкэнда не является опцией, можно указать Nginx игнорировать Set-Cookie заголовок

proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";

посмотреть документация

proxy_ignore_header гарантирует, что кэширование происходит. proxy_hide_header обеспечит грузоподъемность печенья не входит в кэшированных данных. Это важно, чтобы избежать утечки файлов cookie через кэш NGINX.

37

автор: Alexander Azarov


Я хотел бы добавить, что несколько параметров конфигурации и комбинаций могут отключить кэширование прокси в Nginx. К сожалению, это плохо документировано.

в моей конфигурации я поставил proxy_buffering on и он включил кэширование, как ожидалось.


для чего это стоит, мой опыт заключается в том, что nginx не всегда кэширует вещи, где вы это говорите.

например, на centos7, с параметром конфигурации

proxy_cache_path /tmp/my_nginx_cache levels=1:2 keys_zone=my_zone:10m inactive=24h max_size=1g;

nginx фактически кэширует файлы по адресу:

/tmp/systemd-private-phJlfG/tmp/my_nginx_cache

после прохождения нескольких ответов и комментариев я обнаружил, что эта конфигурация, наконец, работает:

10m = 10Mb Key cache, max_size до 2GB, inactive=120m (обновление от источника после 120minutes неактивного), use_temp_path=off (для уменьшения ввода-вывода)

proxy_cache_valid-состояние кэша 200 и 302 для 60minutes

proxy_cache_path /tmp/cache levels=1:2 keys_zone=default_cache:10m max_size=2g
                 inactive=120m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 60m;

server {
    listen       80;
    server_name  example.com;

    # https://www.nginx.com/blog/nginx-caching-guide
    location / {
        proxy_cache default_cache;
        proxy_buffering on;
        proxy_ignore_headers Expires;
        proxy_ignore_headers X-Accel-Expires;
        proxy_ignore_headers Cache-Control;
        proxy_ignore_headers Set-Cookie;

        proxy_hide_header X-Accel-Expires;
        proxy_hide_header Expires;
        proxy_hide_header Cache-Control;
        proxy_hide_header Pragma;

        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_pass http://ip-of-host:80;

        #set            $memcached_key "$uri?$args";
        #memcached_pass 127.0.0.1:11211;
        # error_page     404 502 504 = @fallback;
    }
}

Исходный адрес:https://blog.csdn.net/dengjiexian123/article/details/53386586/

Предисловие:

Благодаря своей работе я занимаюсь вебкастингом, в котором для воспроизведения и загрузки видео используются некоторые технологии загрузки видео. Текущий основной подход на рынке для загрузки полного видео заключается в том, чтобы сначала нарезать весь видеопоток и сохранить его на файловом сервере, когда пользователю необходимо просмотреть воспроизводимое видео. Передайте видео обратно на исходный сервер, перейдите на файловый сервер, чтобы запросить фрагменты один за другим и вернуть их пользователю для воспроизведения.

Сегодня я сосредоточусь на настройке кэширования обратного сервера и разумных стратегиях кэширования.

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

Сегодняшнее объяснение разделено на четыре пункта:

  • Какова работа сервера возврата к источнику
  • Зачем нужно добавлять кеширование на исходный сервер
  • Как настроить кеш
  • Как настроить полный механизм кеширования для бизнес-сценариев

Работа back-to-origin сервера:

Сервер обратного происхождения упоминается как исходная станция в следующем описании.

Как показано на рисунке, в процессе загрузки файла он проходит между CDN и файловым сервером в качестве концентратора загрузки.

Архитектура исходного сайта: исходный сайт — это архитектура веб-сервера nginx + php, как показано на рисунке:

Но если исходный сайт просто получает запрос, загружает ресурс и затем возвращается, обязательно возникнут следующие проблемы, которые не будут оптимизированы:

1. CDN может иметь многократное возвращение к источнику.

2. Множественные загрузки одного и того же ресурса исходным сайтом приведут к потере полосы пропускания сетевого трафика и ненужным затратам времени.

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

Принцип proxy_cache:

Принцип работы модуля proxy_cache показан на рисунке:

Как настроить модуль proxy_cache

Добавьте следующий код в файл nginx.conf:

 
  1. http{

  2. ......

  3. proxy_cache_path/data/nginx/tmp-test levels=1:2 keys_zone=tmp-test:100m inactive=7d max_size=1000g;

  4. }

Описание кода:

proxy_cache_path Путь к кеш-файлу

Уровни Устанавливает уровень каталога файлов кэша; уровни = 1: 2 указывает на два уровня каталога.

keys_zone Установить имя кеша и размер разделяемой памяти

неактивно Удаляется, если никто не посещает в течение указанного времени

max_size Максимальное пространство кэша. Если пространство кэша заполнено, ресурс с наибольшим временем кеширования будет перезаписан по умолчанию.

После завершения настройки перезапустите nginx, если об ошибках не сообщается, настроенный proxy_cache вступит в силу

Проверьте каталог proxy_cache_path / data / nginx /,

Вы обнаружите, что создана папка tmp-test.

Как использовать proxy_cache

Добавьте следующий код в соответствующий файл конфигурации сервера nginx vhost:

 
  1. location /tmp-test/ {

  2. proxy_cache tmp-test;

  3. proxy_cache_valid 200 206 304 301 302 10d;

  4. proxy_cache_key $uri;

  5. proxy_set_header Host $host:$server_port;

  6. proxy_set_header X-Real-IP $remote_addr;

  7. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  8. proxy_passhttp://127.0.0.1:8081/media_store.php/tmp-test/;

  9. }

Введение в элемент конфигурации:

Proxy_cache tmp-test использует соответствующую конфигурацию кеша с именем tmp-test

proxy_cache_valid 200 206 304 301 302 10d; кеш на 10 дней для httpcode 200 …

proxy_cache_key $ uri Определяет уникальный ключ кеша и обращается к хешу через уникальный ключ

proxy_set_header Пользовательский заголовок HTTP-заголовка, используемый для отправки на внутренний реальный сервер.

proxy_pass относится к пути пересылки после прокси, обратите внимание, является ли последний /

На этом этапе самая основная функция proxy_cache успешно настроена. Когда uri успешно совпадает с местоположением, proxy_cache вступит в силу.

После добавления proxy_cache изменения в процессе запроса:

1. Первое посещение:

При первом посещении proxy_cache не нашел соответствующий файл кеша (отсутствует кеш MISS), поэтому при выполнении первого запроса proxy_cache сохранит кеш:

2. Сохраните кеш, как показано на рисунке:

3. При повторном обращении к тому же URL-адресу, когда тот же файл снова поступает на исходный сайт, proxy_cache найдет соответствующий ему файл кеша (ударит HIT кеша) и вернет его непосредственно запрашивающей стороне без выполнения программы PHP, как показано на рисунке:

Задайте вопрос:

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

  1. Необходимо активно очищать файлы кеша
  2. Путь записи — диск. Что делать, если диск заполнен?
  3. Как сделать так, чтобы исходный сайт поддерживал возобновляемую передачу и стратегию кэширования возобновляемой передачи
  4. Если запрашивающая сторона запрашивает запрос диапазона (сегментированная загрузка) для большого ресурса и того же URI, как отличить запрос?
  5. Вам также необходимо сообщить запрашивающей стороне время истечения срока действия ресурса.
  6. Журнал статистики, как настроить поля попаданий и промахов и как вести статистику?

Столкнувшись с вышеуказанными вопросами, мы решаем их по очереди.

Вопрос 1: заранее очистите кеш

Принять: модуль nginx proxy_cache_purge, который появляется в паре с proxy_cache, а функция как раз наоборот.

Метод разработки: в nginx запустите другой сервер и, когда вам нужно очистить кеш ресурсов ответа, обратитесь к этому серверу на локальном компьютере.

Например:

Посетите 127.0.0.1:8083/tmp-test/TL39ef7ea6d8e8d48e87a30c43b8f75e30.txt, чтобы очистить файл кеша этого ресурса.

Метод конфигурации:

 
  1. location /tmp-test/ {

  2. allow 127.0.0.1; // Разрешить только локальный доступ

  3. deny all; // Запрещаем все остальные ip

  4. proxy_cache_purge tmp-test $ uri; // Очистить кеш

  5. }

proxy_cache_purge: модуль очистки кеша

tmp-test: указанная key_zone

$ uri: указанные параметры для генерации ключа

Процесс очистки кеша proxy_cache_purge, как показано на рисунке:


 

Вопрос 2: Что делать, если кеш-файл заполнен диском?

Поскольку путь записи — это один каталог, можно записать только один диск. Диск скоро заполнится. Есть два способа решить эту проблему:

1. Будет ли несколько дисков использоваться как дисковый массив? Недостатком является то, что фактическое пространство для хранения уменьшается.

2. Используйте структуру каталогов proxy_cache_path с умом. Поскольку уровни = 1: 2, это приводит к двухуровневой структуре каталогов для файла кэша, а имя каталога каждого уровня генерируется хеш-функцией. как показано на картинке:

Всего имеется 16 * 16 * 16 = 4096 файловых каталогов. Создайте мягкую ссылку на каталог первого уровня и, соответственно, мягкую ссылку 0-f на указанный каталог диска, который вам нужен, как показано на рисунке:

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

Вопрос 3: Диапазон поддержки (возобновление точки останова)

После добавления прокси-сервера кеша запрос диапазона, инициированный клиентом, станет недействительным, как показано на следующем рисунке:

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

Когда прокси-сервер кеша пересылает http-запрос на внутренний сервер, заголовок http изменится, и некоторые параметры в заголовке будут отменены. Среди них был отменен параметр диапазона, в результате чего внутренний сервер nginx не получил параметр диапазона, что в итоге привело к неудачной загрузке этого сегмента. Итак, вам нужно настроить заголовок, пересылаемый прокси.

Например:

 
  1. location /tmp-test/ {

  2. proxy_cache tmp-test;

  3. proxy_cache_valid 200 206 304 301 302 10d;

  4. proxy_cache_key $uri;

  5. <span style="color:#ff0000;">proxy_set_header Range $http_range;</span>

  6. proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/;

  7. }

Значение красной части: поместите значение диапазона ($ http_range) в HTTP-запросе в заголовок HTTP-запроса, пересылаемый прокси-сервером в качестве значения диапазона параметров.

Вопрос четвертый, после поддержки загрузки диапазона необходимо перенастроить proxy_cache_key:

Если запрашивающий диапазон запрашивает (фрагментированную загрузку) большой ресурс, тот же uri, как кеш прокси определяет ключ, соответствующий ресурсу?

Поскольку nginx настроен как proxy_cache_key $ uri, используйте uri в качестве ключа

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

Решение такое:

Измените proxy_cache_key, настройте proxy_cache_key $ http_range $ uri;

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

Вопрос 5: Как настроить-вернуть срок годности

Необходимо указать инициатора запроса, вернув время истечения срока действия, какие ресурсы необходимо кэшировать, а какие не кэшируются,

параметр Нормальный запрос запрос диапазона
Срок годности возврата возвращаться Не возвращайся

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

Чтобы решить эту проблему, ее можно решить, настроив nginx:

 
  1. location /media_store.php {

  2. fastcgi_pass 127.0.0.1:9000;

  3. fastcgi_index media_store.php;

  4. fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

  5. include fastcgi_params;

  6. if ( $http_range = ''){

  7. expires 2592000s;

  8. }

  9. }

Добавьте оценку $ http_range к местоположению после proxy_pass, и expires представляет время истечения срока. 2592000 с — время истечения срока действия кеша.

Вопрос 7: Как отразить попадания в кеш в заголовке http и просмотреть его в журнале nginx

Решение:

Используйте переменную nginx $ upstream_cache_status: эта переменная представляет состояние попаданий в кеш,

При попадании — УДАРЕ; при промахе — ПРОПУСТИТЬ.

Добавьте в возвращаемую конфигурацию сервера nginx:

add_header  Nginx-Cache «$upstream_cache_status»;

Добавьте в nginxlog:

log_format       combinedio  …$upstream_cache_status;

http return head скриншот:

Снимок экрана журнала nginx:

подводить итоги:

Здесь представлен полный набор полных стратегий кэширования.Этот набор решений не только реализует базовую конфигурацию кеша, но также решает проблемы, возникающие в реальных приложениях сцены, такие как расширение диска, очистка кеша, возобновляемая загрузка и время истечения срока действия кеша. , Кэшируйте подсказки о попаданиях и другие проблемы, пока этот набор решений используется гибко, независимо от того, насколько сложна сцена, он в основном может удовлетворить потребности. Выше перечислены все ямы, через которые я пролез в своей работе, и результаты, обобщенные путем постоянного улучшения, я надеюсь, что это будет полезно для читателей.

Централизованный выход в Интернет через один сервер в сети (proxy)

В корпоративных сетях является стандартной ситуация, когда, с одной стороны, множество пользователей на разных компьютерах пользуются ресурсами сети Интернет, при этом обеспечить надлежащий уровень безопасности на этих компьютерах одновременно довольно сложно. Ещё сложнее заставить пользователей соблюдать некий «корпоративный стандарт», ограничивающий возможности использования Интернет (например, запретить использование определённого типа ресурсов или закрыть доступ к некоторым адресам).

Простейшим решением будет разрешить только определённые методы доступа к Интернет (например, по протоколам HTTP и FTP) и определить права доступа абонентов на одном сервере, а самим абонентам разрешить только обращение к этому серверу по специальному прокси-протоколу (поддерживается всеми современными браузерами). Сервер же, после определения прав доступа, будет транслировать (проксировать) приходящие на него HTTP-запросы, направляя их адресату. Допустим, несколько пользователей с нескольких компьютеров внутренней сети просматривают некоторый сайт. С точки зрения этого сайта их активность представляется потоком запросов от одного и того же компьютера.

Обычный доступ

Непосредственно после установки Squid уже поддерживает функции прокси, но принимает соединения только с того компьютера, на который установлен. Для того, чтобы можно было воспользоваться этим сервисом с других компьютеров, необходимо изменить т. н. таблицы управления доступом (Access Control Lists, далее ACL), находящиеся, как и большинство настроек Squid, в файле /etc/squid/squid.conf. Файл этот снабжён подробными комментариями и примерами по всем настройкам в виде комментариев, например, так:

 # TAG: <некоторая_настройка>

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

 acl our_networks src 192.168.1.0/24 192.168.2.0/24
 http_access allow our_networks

Следует иметь в виду, что при обработке запроса на доступ к Squid все строки http_access файла squid.conf просматриваются последовательно сверху вниз до первой строки, соответствующей параметрам запроса. Это означает, что важен порядок следования строк http_access.

Анонимизирующий доступ

При использовании прокси-сервера остаётся некоторая угроза безопасности, связанная с тем, что топология внутренней сети и активность её абонентов не маскируются. Например, в протоколе HTTP используются т.н. заголовки (headers), значения которых заполняются браузерами при отправлении запроса. Squid умеет удалять опасные поля заголовка из запроса при помощи настройки header_access или подменять их значения на другие, заранее заданные, при помощи настройки header_replace. Варианты использования этих настроек приведены в squid.conf в районе TAG: header_access и TAG: header_replace, соответственно. 

Имейте в виду, что из-за удаления и/или подмены полей заголовков может нарушиться связь с некоторыми системами, использующими значение этих полей для организации взаимодействия и авторизации.

«Прозрачный» доступ

Можно вообще не сообщать пользователям сети, что в ней используется прокси-сервер. Если прокси-сервер — одновременно и маршрутизатор, весь сетевой трафик в любом случае его не обойдёт. При этом можно средствами межсетевого экрана все обычные HTTP-запросы к удалённым серверам перенаправлять на вход особым образом настроенного Squid. С внешней стороны это будет выглядеть обычным прокси-сервером, а со стороны пользователя — ничем не будет отличаться от обычной работы в сети. Команда iptables, перенаправляющая HTTP-запросы к внешним серверам на порт Squid может, например, выглядеть так:

 iptables -t NAT -A PREROUTING -d ! <адрес_самого_сервера>  
 -i <внутренний_сетевой_интерфейс> -p tcp -m tcp --dport 80  
 -j REDIRECT --to-ports 3128 

Или так:

 iptables -t nat -A PREROUTING -p tcp -d 0/0 --dport www  
 -i <внутренний_сетевой_интерфейс> -j DNAT  
 --to <локальный_адрес_на_котором_слушает_прокси>:3128

Настройка squid.conf при этом использует обратное проксирование, описанное ниже. Как сказано в документации по Squid, для организации прозрачного прокси достаточно добавить в squid.conf строку:

 http_port 80 intercept

Фильтрация доступа

В Squid существует гибкая схема фильтрации внешних ссылок. С её помощью, например, можно закрыть доступ к определённым сайтам и ресурсам на них, избавиться от навязчивой рекламы (banners), ссылок непристойного содержания и т. п. Содержимое фильтруется с помощью всё тех же ACL и настроек http_access deny, примеры которых приведены в squid.conf

Обратите внимание, что при задании фильтруемого URL или доменного имени сервера можно использовать регулярные выражения, таким образом в одной строке определяя фильтр для целого класса адресов или доменных имён. Подробнее о регулярных выражениях можно прочитать в руководстве regex. Запрет доступа к домену baddomain.com, например, можно оформить в виде строк

 acl Bad dstdomain baddomain.com
 http_access deny Bad

Заметим также, что http_access deny Bad следует помещать перед строками вида http_access allow, в этом случае доступ к любому сайту домена будет закрыт безусловно.

Авторизация доступа

В Squid есть возможность определять различные ACL разным пользователям и/или категориям пользователей. Если для определения того, какой именно пользователь подключается к серверу, недостаточно IP-адреса его компьютера, следует воспользоваться одной из многих схем авторизации, принятых в Squid. Авторизация конфигурируется с помощью тега TAG: auth_param. Посмотреть, какие схемы (программы) авторизации поддерживает Squid, можно в каталоге /usr/lib/squid.

Например, настройка авторизации в LDAP может выглядеть так:

 auth_param basic program /usr/lib/squid/squid_ldap_auth -b ou=People,dc=office,dc=lan -f (uid=%s) -h ldap.office.lan auth_param basic children 5 
 auth_param basic realm Squid proxy-caching web server auth_param basic credentialsttl 2 hours 

Информацию по настройке той или иной программы авторизации можно почерпнуть из соответствующих руководств.

Локальное хранение данных, которые уже запрашивались пользователями (cache)

Не менее важное свойство Squid состоит в том, что данные, полученные по запросам из сети Интернета, сохраняются в системе (кешируются). При повторных запросах данные будут предоставляться не из сети Интернет, а из сохранённой копии. Объекты кешируются до тех пор, пока не истечёт их «срок годности» или пока они не будут вытеснены другими, более часто используемыми. Например, если все пользователи внутренней сети одновременно работают с одним и тем же сайтом в сети, общий поток запросов от Squid будет несравненно меньше потока пользовательских запросов, так как большинство ресурсов сайта уже будет находиться в кеше.

Обычное кеширование

Непосредственно после установки сервера он уже выполняет кеширующие функции. Кеширование позволяет не только сэкономить на оплате трафика, но и уменьшить время доступа к ресурсам Интернет. Однако следует понимать, что снижение внешнего трафика возможно только если один и тот же ресурс был запрошен несколькими пользователями на протяжении некоторого промежутка времени. Если пользовательские запросы почти не пересекаются, снижение трафика может быть незначительным.

Кроме того, кеширование неэффективно в ситуации, когда повторный запрос на большинство объектов приходит уже после того, как эти объекты вытесняются из кеша более новыми. Если анализ статистики показывает, что происходит именно это, можно попробовать увеличить объём кешируемой информации. Настройки Squid, отвечающие за размер кеша, приведены в файле squid.conf в разделе, начинающемся словами OPTIONS WHICH AFFECT THE CACHE SIZE.

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

Выборочное кеширование

Некоторые данные (например, очень большие файлы, автоматически изменяемые WWW-страницы, звуки и т. п.) кешировать невыгодно: вероятность повторного запроса в течение “срока годности” низкая, а других объектов вытесняется много. С другой стороны, содержимое некоторых сайтов может понадобиться кешировать в обязательном порядке (например, для ускорения доступа). Эти свойства управляются, как обычно, при помощи ACL и настроек always_direct (без кеширования) и never_direct (обязательное кеширование). 

Например, чтобы предотвратить кеширование файлов, получаемых по протоколу FTP (это, как правило, разумно), необходимо в соответствующем месте squid.conf раскомментировать строки:

 acl FTP proto FTP
 always_direct allow FTP

Иерархия серверов

Если запрашиваемый ресурс не найден в локальном кеше Squid, он может попытаться запросить его у «вышестоящих» серверов или у «соседей» — вместо того, чтобы обращаться в Интернет. Таким вышестоящим сервером (parent peer) может быть сервер провайдера, а соседом (sibling peer) — сервер абонента, подключённого к тому же провайдеру. Правила передачи объектов кеша и формирования иерархии серверов описаны в документации Squid. Раздел конфигурационного файла, отвечающий за механизм обмена кешем, начинается словами OPTIONS WHICH AFFECT THE NEIGHBOR SELECTION ALGORITHM.

Необходимо знать, что обмен содержимым кеша требует непременной авторизации доступа между серверами (во избежание подлогов и другого вида атак). Все параметры соединения сервера с сервером (настройка cache_peer) записываются в текстовом виде, включая пароли, так что следует строго ограничить доступ к файлу настройки squid.conf.

Обратное проксирование и кеширование внутренних серверов (accelerate)

Кеширующие и проксирующие способности Squid можно использовать и «в обратную сторону», пропуская через сервер входящие запросы на внутренние серверы. Таким образом, можно скрыть реальное расположение и структуру серверов, и уменьшить нагрузку на них.

Обычное обратное проксирование (один сервер)

В режиме accelerate сервер сам принимает извне HTTP-запросы, адресованные, как правило на 80-й порт. Кроме того, необходимо указать имя сервера и порт, на который будут проксироваться запросы. Это можно сделать, например, так:

 http_port 80 defaultsite=internal.www.com 
 cache_peer 192.168.1.1 parent 80 0 no-query originserver 

Если необходимо как-то ограничить доступ к внутреннему серверу, это легко сделать, применив соответствующие ACL.

Множественное проксирование

Для обратного проксирования нескольких внутренних серверов необходимо, чтобы внешние запросы на сайты с разными доменными именами попадали на вход Squid, который бы ставил в соответствие каждому имени действительный адрес сервера во внутренней сети и перенаправлял бы запрос туда. Делается это с помощью механизма виртуальных хостов. Вот как, например, можно организовать прокси для двух серверов, www1.foo.bar и www2.foo.bar, адреса которых в DNS указывают на машину со Squid-сервером (файл /etc/squid/squid.conf):

 http_port 80 defaultsite=www1.foo.bar vhost
 hosts_file /etc/hosts

Настройка defaultsite нужна серверу для заполнения HTTP-заголовков. Соответствие доменных имён адресам серверов во внутренней сети разумно получать из стандартного файла /etc/hosts:

 10.0.0.1      www1.foo.bar 
 10.0.0.2      www2.foo.bar 

Множественное обратное проксирование имеет важный побочный эффект. В сетях, подключённых к Интернету постоянно, нередки случаи, когда недобросовестные администраторы внутренних сайтов регистрируют их в других доменах и используют их в качестве хостинг-платформ, часто с документами незаконного или нецензурного содержания. 

Допустим, сайт www1.foo.bar также зарегистрирован как www.verycoolwarez.com, и по этому адресу доступны контрафактные версии программ и т. п. В обычном случае для обнаружения этого факта необходимо анализировать трафик, делать внушение администратору www1.foo.bar и т.д. При использовании обратного проксирования такого вообще не может произойти без договорённости с администратором Squid, то есть без занесения в /etc/hosts!

Разное

Безопасность

Squid поддерживает проксирование разнообразных протоколов, использование которых необходимо контролировать на уровне прав доступа. Если прокси-сервер — анонимизирующий, им могут воспользоваться нарушители, чтобы скрыть обратный адрес при незаконном доступе к данным или даже атаке на другие серверы.

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

Сбор статистики и ограничение полосы доступа

В Squid входит утилита кеш-менеджер, служащая для отображения статистики и загрузки сервера. Кеш-менеджер представляет собой cgi-приложение и должен выполняться под управлением сконфигурированного HTTP-сервера. Все настройки кеш-менеджера также производятся в /etc/squid/squid.conf, строки, которые относятся к кеш-менеджеру, обычно включают cachemgr.

При помощи Squid можно ограничить полосу пропускания («толщину канала») для пользователей. За это отвечают параметры delay_pools и delay_class. Эта технология позволит вам снизить загрузку канала, например, большими по объёму медиафайлами, и отдать полосу какому-то более приоритетному трафику.

Кеширование DNS-запросов

Squid содержит встроенный минисервер запросов DNS. Он выступает как посредник между Squid и внешними DNS-серверами. При запуске Squid производит начальное тестирование доступности DNS и интернет в целом. Это можно отключить, используя опцию -D. Время кеширования удачного DNS-запроса по умолчанию составляет шесть часов.

Дата последнего изменения: 14.12.2022

Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.

В nginx начаная с версии 0.7.44 появилась возможность кешировать отдаваемые страницы, что может увеличить работы сайта в тысячу раз.

Рассмотрим практический пример настройки кеширования. За основу будет взят сайт контент которого не меняется в зависимости от пользователя (авторизован или гость) и нет активно меняющихся данных (например голосований). Это важно, т.к. активно изменяющийся контент требует индивидуального подхода и зачастую сложных схем кеширования.

В nginx кеширование отдельно настраевается для модулей proxy и fastcgi, ниже насмотрена настройка для модуля proxy, чтобы заработало для fastcgi замените директивы proxy_cache* на fastcgi_cache*.

Настройка общая

За основу будет взят сайт контент которого не меняется в зависимости от пользователя (авторизован или гость) и нет активно меняющихся данных (например голосований). Это важно, т.к. активно изменяющийся контент требует индивидуального подхода и зачастую сложных схем кеширования.

Сперва создадим папку в которой nginx будет хранить данные кеша.

mkdir /var/cache/nginx
chown nginx:nginx /var/cache/nginx/

В главной конфигурации в разделе http {…} указываем эту папку:

/etc/nginx/nginx.conf

...
## Создаем кеш зону pagecache (память под ключи в 5Мб) с настройками:
# inactive: xранить кеш 10 минут
# max_size: максимальный размер кеш данные 50Мб
proxy_cache_path /var/cache/nginx levels=2 keys_zone=pagecache:5m inactive=10m max_size=50m;
...

Теперь в конфигурации server {…} добавим:

server {
...
        # Кешировать указанные коды ответов 5 минут
	proxy_cache_valid 200 301 302 304 5m;
        # Ключ по которому сохраняются и берутся данные из кеша
	proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
        # Защита от раздачи одинаковой куки в кешированном ответе
	proxy_hide_header "Set-Cookie";
        # Игнорировать параметры кеша заданные бекэндом
	proxy_ignore_headers "Cache-Control" "Expires";

        # Указывает в каких случаях клиенту можно отдать несвежий ответ из кеша
	proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;

        # активировать зону кеширования pagecache
        proxy_cache	pagecache;
...
}

Последняя запись proxy_cache pagecache активирует работу кеша. Если она написана в теле секции server, то кеш будет отрабатывать для всего сайта. Так же эту строчку можно поместить в конкретный location и догда кеш будет работать только для него.

Чтобы отключить кеширование для конкретного локейшена то укажите внутри него proxy_cache off.

Настройка с разделением пользователь-гость

Далее приводиться более сложный пример настройки кеширования nginx с разделением на гостей и авторизованных пользователей.

Принцип действия:

  • гостям данные отдаются из кеша (обновляются согласно настройкам кеширования — proxy_cache_valid)

  • авторизованным пользователям данные всегда отдаются напрямую, кроме случая когда:

    • бекэнд сервер выдает ошибку определенную в proxy_cache_use_stale

  • если бекэнд не работает или выдает ошибку определенную в proxy_cache_use_stale гостю выдается ответ из кеша не зависимо от его устаревания

  • определение зарегистрированного пользователя осуществляется по наличию определенной куки (её название зависит от движка сайта)

В конфиге nginx в секции http {…} добавляем строчку определения кеша:

## Создаем кеш зону pagecache (память под ключи в 15Мб) с настройками:
# inactive: xранить кеш 60 минут
# max_size: максимальный размер кеш данные 500Мб
proxy_cache_path /var/cache/nginx levels=2 keys_zone=pagecache:15m inactive=60m max_size=500m;

В секции server {…}:

server {
	listen          *:80;
	server_name     site.name;

	# ключ по которому сохраняются и берутся данные из кеша
	proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
	# Указывает в каких случаях клиенту можно отдать несвежий ответ из кеша
	proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;

	location / {
		# оригинальный url (нужен для кеширования)
		set $o_uri $request_uri;

		# Определение пользователя по куке LOGIN (замените на свою)
		if ( $cookie_LOGIN = "" ) {
			# если кука LOGIN не установлена обрабатывать запрос через кеш
			rewrite ^ /ng_cache last;
		}

		# Для авторизованных отдать данные напрямую
		proxy_cache		pagecache;
		proxy_cache_valid	any 0;

		proxy_pass              http://10.0.1.26;
		proxy_set_header        Host             $host;
		proxy_set_header        X-Real-IP        $remote_addr;
	}

	# !Важно! url по которому осуществляется авторизвация
	# и устанавливается определяющая кука (LOGIN)
	location /login {
		proxy_pass              http://10.0.1.26;
		proxy_set_header        Host             $host;
		proxy_set_header        X-Real-IP        $remote_addr;
	}

        # Учтите что кешируется весь ответ от беэнда, если хотите исключить некоторые файла, то
        # добавте эту настройку. Исключаем картинки, видео, музыку, архивы:
	location ~* .(jpe?g|gif|png|tif|svg|mp3|ogg|avi|mpe?g|zip|gz|bz2?|rar|ico|bmp|swf|txt|xml)$ {
                proxy_pass              http://10.0.1.26;
                proxy_set_header        Host             $host;
                proxy_set_header        X-Real-IP        $remote_addr;
	}

	# Обработка через кеш
	location /ng_cache {
		internal;

		# активировать зону кеширования pagecache
		proxy_cache		pagecache;
		# Кешировать указанные коды ответов 10 минут
		proxy_cache_valid	200 301 302 304 10m;
		# Защита от раздачи одинаковой куки в кешированном ответе
		proxy_hide_header	"Set-Cookie";
		# Игнорировать параметры кеша заданные бекэндом
		proxy_ignore_headers	"Cache-Control" "Expires";

		# Получение данных от бекэнда по оригинальному url
		proxy_pass              http://10.0.1.26:80$o_uri;
		proxy_set_header        Host             $host;
		proxy_set_header        X-Real-IP        $remote_addr;
	}
}


Post Views:
1 667

Я пытаюсь кэшировать статический контент, который в основном находится внутри путей ниже в конфигурации виртуального сервера. По какой-то причине файлы не кэшируются. Я вижу несколько папок и файлов внутри кэша dir, но его всегда что-то вроде 20mb не выше, не ниже. Если бы это было кэширование изображений, например, заняло бы не менее 500 МБ пространства.

вот nginx.часть кэша conf:

** nginx.conf **
proxy_cache_path /usr/share/nginx/www/cache levels=1:2 keys_zone=static$
proxy_temp_path /usr/share/nginx/www/tmp;
proxy_read_timeout 300s;

вот виртуальный сервер по умолчанию.

**sites-available/default**
server {
    listen   80; 

    root /usr/share/nginx/www;
    server_name myserver;
    access_log /var/log/nginx/myserver.log main;
    error_log /var/log/nginx/error.log;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location ~* ^/(thumbs|images|css|js|pubimg)/(.*)$ {
            proxy_pass http://backend;
            proxy_cache static;
            proxy_cache_min_uses 1;
            proxy_cache_valid 200 301 302 120m;
            proxy_cache_valid 404 1m;
            expires max;
    }

    location / {
            proxy_pass http://backend;
    }
}

4 ответов


убедитесь, что ваш сервер не возвращает Set-Cookie заголовок. Если Nginx видит его, он отключает кэширование.

если это ваш случай, лучшим вариантом является исправление вашего бэкэнда. Когда исправление бэкэнда не является опцией, можно указать Nginx игнорировать Set-Cookie заголовок

proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";

посмотреть документация

proxy_ignore_header гарантирует, что кэширование происходит. proxy_hide_header обеспечит грузоподъемность печенья не входит в кэшированных данных. Это важно, чтобы избежать утечки файлов cookie через кэш NGINX.

37

автор: Alexander Azarov


Я хотел бы добавить, что несколько параметров конфигурации и комбинаций могут отключить кэширование прокси в Nginx. К сожалению, это плохо документировано.

в моей конфигурации я поставил proxy_buffering on и он включил кэширование, как ожидалось.


для чего это стоит, мой опыт заключается в том, что nginx не всегда кэширует вещи, где вы это говорите.

например, на centos7, с параметром конфигурации

proxy_cache_path /tmp/my_nginx_cache levels=1:2 keys_zone=my_zone:10m inactive=24h max_size=1g;

nginx фактически кэширует файлы по адресу:

/tmp/systemd-private-phJlfG/tmp/my_nginx_cache

после прохождения нескольких ответов и комментариев я обнаружил, что эта конфигурация, наконец, работает:

10m = 10Mb Key cache, max_size до 2GB, inactive=120m (обновление от источника после 120minutes неактивного), use_temp_path=off (для уменьшения ввода-вывода)

proxy_cache_valid-состояние кэша 200 и 302 для 60minutes

proxy_cache_path /tmp/cache levels=1:2 keys_zone=default_cache:10m max_size=2g
                 inactive=120m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 60m;

server {
    listen       80;
    server_name  example.com;

    # https://www.nginx.com/blog/nginx-caching-guide
    location / {
        proxy_cache default_cache;
        proxy_buffering on;
        proxy_ignore_headers Expires;
        proxy_ignore_headers X-Accel-Expires;
        proxy_ignore_headers Cache-Control;
        proxy_ignore_headers Set-Cookie;

        proxy_hide_header X-Accel-Expires;
        proxy_hide_header Expires;
        proxy_hide_header Cache-Control;
        proxy_hide_header Pragma;

        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_pass http://ip-of-host:80;

        #set            $memcached_key "$uri?$args";
        #memcached_pass 127.0.0.1:11211;
        # error_page     404 502 504 = @fallback;
    }
}

Понравилась статья? Поделить с друзьями:
  • Proxmox ошибка 401 permission denied invalid pve ticket
  • Proxmox novnc ошибка подключения к серверу
  • Provisional headers are shown ошибка
  • Provider sql network interfaces error 26 ошибка при обнаружении
  • Protherm lynx 24 коды ошибок