Как настроить Nginx в качестве кеширующего обратного прокси?

143

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

Я хочу настроить Nginx в качестве обратного кеширующего прокси-сервера перед Apache / Django: иметь прокси-запросы Nginx для некоторых (но не всех) динамических страниц к Apache, затем кэшировать сгенерированные страницы и обслуживать последующие запросы этих страниц из кеша.

В идеале я бы хотел сделать кеш недействительным двумя способами:

  1. Установить срок действия для кэшированного элемента
  2. Явно лишить законной силы кэшированный элемент. Например, если мой бэкэнд Django обновил определенные данные, я бы хотел сказать Nginx, что нужно сделать недействительным кеш поврежденных страниц.

Можно ли настроить Nginx для этого? Как?

продолжение
источник
Не проверено, но от gumroad.com/l/ngx_purge : «ngx_purge - это чистый модуль Lua для Nginx, который позволяет пользователю удалять объекты из кэша nginx.».
Хайме Хаблуцель

Ответы:

97

Я не думаю, что есть способ явно аннулировать кэшированные элементы, но вот пример того, как сделать все остальное. Обновление: Как упоминал Петр в другом ответе, есть модуль очистки кэша, который вы можете использовать. Вы также можете принудительно обновить кэшированный элемент, используя progin_cache_bypass от nginx - для получения дополнительной информации см . Ответ Чериана .

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

Ваши HTTP-заголовки Cache-Control и Expires будут учтены, поэтому, если вы хотите явно установить дату истечения срока действия, вы можете сделать это, установив правильные заголовки в том, к чему вы используете прокси.

Существует множество параметров, которые вы можете настроить - см. Документацию модуля прокси-сервера nginx для получения дополнительной информации обо всем этом, включая сведения о значении различных настроек / параметров: http://nginx.org/r/proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}
Casey
источник
7
Это разумный первый шаг для новых приложений, которые не имеют 20k / req / s.
5
@ Барри, какой будет второй степ?
Юрген Павел
42
@ Legit - я не знаю, но традиционно последний шаг - «Прибыль» :-)
Стивен С.
К сожалению, он не работает с nginx 1.11. Поскольку последнее обновление было около 3 лет назад, похоже, это уже не решение.
izogfif
Что означает: inactive=600mзначит? Разве не inactiveдолжно быть время? `[inactive=time]
NeverEndingQueue
47

Вы можете специально аннулировать кэшированные страницы через

proxy_cache_bypass       

Скажем, вы хотите кешировать страницу, установите кеш таким образом

location = /pageid {
  proxy_pass http://localhost:82;
  proxy_set_header   Host             $host;
  proxy_set_header   X-Real-IP        $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  proxy_ignore_headers Set-Cookie; 
  proxy_ignore_headers Cache-Control; 
  proxy_cache_bypass        $http_secret_header;
  add_header X-Cache-Status $upstream_cache_status;
}

Теперь, когда вы хотите аннулировать эту страницу и снова кешировать

Сделайте секретный вызов curl с заголовком

curl "www.site.com/pageid" -s -I -H "secret_header:true" 

Это сделает недействительным и кэшировать его.

Работает от nginx 0.7.

В качестве дополнительного бонуса add_header X-Cache-Statusможно использовать, чтобы проверить, находится ли страница из кэша или нет.

Cherian
источник
Это может обновлять кэшированные страницы только тогда, когда новая страница также кэшируется. Если вы удалили страницу (теперь 404 или другие ошибки теперь обслуживаются бэкэндом), страница теперь отправляет Set-Cookie или заголовок «Content-Control: private», кэшированное содержимое не будет «признано недействительным».
СБР
36

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

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

Дейв Чейни
источник
Не могли бы вы объяснить, что вы имели в виду под «переименованием файла или использованием какой-либо формы уничтожения кеша строки запроса»? Я не уверен, что понимаю, почему не стоит использовать такую ​​операцию, как PURGE.
продолжение
5
+1 за лак. Всегда лучше использовать правильные инструменты для работы.
Том О'Коннор
4
@ ниже: почти нет надежды прикоснуться к лаку на аренах производительности и универсальности. Это поддерживается одним из ведущих разработчиков ядра FreeBSD и специальной командой из Европы. Лак находится в производстве на твиттере, героку и многих других.
2
Простейший пример разгона кэша - это добавление номера версии в строке запроса к статическому ресурсу, поэтому style.css становится style.css? 123. Когда вы хотите отправить новую версию файла, вы изменяете URL ресурса на style.css? 124, и теперь кеши выбирают его как совершенно новый ресурс для отдельного кэширования. Apache будет обслуживать файл style.css с добавленной строкой запроса, поэтому никаких изменений в реальном файле не требуется.
Chmac
3
Если возможно, лучше всего поместить кеш-буфер в само имя файла, например, style.v123.cssпотому что некоторые кеши не будут кешировать запросы, содержащие строку запроса.
Ноа Макилрейт
8

Для аннулирования выбранных страниц вы можете использовать патч «cache_purge» для nginx-0.8.x, который делает именно то, что вы хотите;)

Это доступно здесь .


источник
8

Большинство инструментов кэширования (Citrix) позволяют принудительное обновление (Ctrl + r) для повторного заполнения кэшированной страницы.

Вот трюк, который я нашел, чтобы сделать что-то похожее в nginx.

server  {
        # Other settings
        proxy_pass_header       Set-Cookie; # I want to cache logged-in users
        proxy_ignore_headers    X-Accel-Redirect;
        proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
        if ($http_cache_control ~ "max-age=0") {set $eac 1;}
        proxy_cache_bypass $eac;
}

Это предполагает, что когда вы делаете Ctrl + r в вашем браузере, заголовок Cache-Control имеет max-age = 0 в своем запросе. Я знаю, что Chrome делает это, но я не пробовал в других браузерах. Добавить больше полей заголовка можно просто, просто добавив больше операторов if, которые устанавливают $eacпеременную в 1.

Рэнди Уоллес
источник
5

Кэширование - довольно новая функция в nginx (и пока не очень хорошо документированная), но достаточно стабильная для использования в производстве.

SaveTheRbtz
источник
4

Я считаю, что NginxHttpProxyModule способен обрабатывать http-запросы. Ищите директивы, начинающиеся с:

proxy_cache

Да, можно контролировать поведение кэша с помощью таких директив:

proxy_cache_valid
Тарас Чухай
источник
3

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

romble
источник
Документация находится здесь: wiki.nginx.org/NginxHttpProxyModule#proxy_cache
rmalayter
2

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

Мартин Мерфи
источник
В самом деле? Похоже, что ngnix соответствует etag и никогда не обращается к приложению, чтобы выяснить, есть ли обновленный etag.
Джон Нэгл
2

Вы можете контролировать срок действия кэша Nginx с помощью нескольких директив / параметров:

  • proxy_cache_valid 200 302 10m;
  • добавив один из заголовков HTTP ниже (приоритет важен - ознакомьтесь с моим постом в блоге ):
    • Expires
    • Cache-Control
    • X-Accel-Expires
  • inactiveпараметр в proxy_cache_pathдирективе:

    proxy_cache_path /data/nginx/cache keys_zone=one:10m inactive=60m;

Я рекомендую мой блог, если вы хотите узнать больше о кэшировании Nginx.

Тема чистки действительно интересна, поскольку эта функция существует только в Nginx Plus (коммерческое издание Nginx). Мне очень нравится ответ @ randy-wallace. Но есть и другие возможности, такие как модуль ngx_cache_purge .

Самое простое, что вы можете сделать, это удалить кэшированный файл вручную:

  • сгенерируйте свой хэш-ключ:

    echo -n ‘httpczerasz.com/time.php’ | md5sum
    
  • удалить файл из файловой системы:

    rm /data/nginx/cache/1/27/2bba799df783554d8402137ca199a271
    
czerasz
источник
1

Для будущих посетителей: Тем временем обратный прокси-сервер nginx имеет встроенное кэширование, и документы доступны по адресу:

Синтаксис: зона proxy_cache | выкл;

По умолчанию: proxy_cache выключен;

Контекст: http, сервер, местоположение

Определяет зону разделяемой памяти, используемую для кэширования. Одну и ту же зону можно использовать в нескольких местах. Значение параметра может содержать переменные (1.7.9). Параметр off отключает кэширование, унаследованное от предыдущего уровня конфигурации.

Тарик Хукласлун
источник
Привет, Тарик, вопрос был очень конкретным о том, что должно быть достигнуто, и это немного больше, чем просто включить кеш.
Asdmin
0
уровни fastcgi_cache_path / opt / nginx-cache = 2: 2 keys_zone = img: 50m;

    местоположение / img / {
        fastcgi_pass $ backend;
        включить fcgi_params;
        fastcgi_intercept_errors off;   
        fastcgi_cache_key $ server_addr $ request_uri;       
        fastcgi_cache img;
        fastcgi_cache_valid any 1m;
        fastcgi_hide_header Set-Cookie;
    }

Это создает кеш для / img / location. Он находится в / opt / nginx-cache. Объекты кэшируются на 1 минуту.

Вы можете написать разные коды ответов вместо любых.

Теперь вы не можете аннулировать кеш для выбранных страниц. Возможно, в 0.8.x это будет возможно.

lexsys
источник
Первоначальный вопрос касался использования nginx перед Apache, а не перед приложением fastcgi, обрабатываемым nginx.
Грэм Дамплтон
0

Существует плагин nginx под названием ncache, который претендует на звание «системы веб-кэша, основанной на веб-сервере nginx. Быстрее и эффективнее, чем squid».

Sajal
источник