[[ Настройка кэширования в nginx ]]

Настройка кэширования в nginx

В 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.

Дополнительная информация

Основные настройки были взяты с сайта http://dklab.ru/chicken/nablas/56.html. Более подробную информацию по работе с кэшом nginx ищите в гугле и на сайте nginx.

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

Далее приводиться более сложный пример настройки кэширования 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;
	}
}

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

Обсуждение

ujcnm, 2011/09/18 11:32

Меня всегда умиляла фраза: Более подробную информацию по работе с кешом nginx ищите в гугле

А как гугл найдет что-то, если все пишут именно так? Ась?

Дмитрий, 2012/11/08 10:01

Жесткие конфиги. Всмысле пиздец говноконфиги.

Николай, 2013/02/21 19:06

To Дмитрий.
В чем они говноконфиги? Самому интересно,потому что тоже кеширующий сервак настраиваю.

Александр, 2013/05/23 12:06

Почему? Хоть один аргумент… Интересно, так как сам экспериментирую с nginx.

виктор, 2013/12/18 17:55

ну для начала копипаст это стремно, и голова лишней не бывает. location ~* \.(jpe?g|gif| заменить на location ~* ^.+\.(jpg|jpeg|js|

Vismuth, 2014/01/17 15:21

Здравствуйте! У меня при этой строчки proxy_cache pagecache; Nginx выдает ошибку

Restarting nginx: nginx: [emerg] "proxy_cache" zone "pagecache" is unknown in /etc/nginx/nginx.conf:535 nginx: configuration file /etc/nginx/nginx.conf test failed

C Чем это связано

nginx version: nginx/1.1.19

Aleksey, 2014/01/17 15:29

proxy_cache_path

copist, 2015/02/18 16:37

О, знакомая цитата с баша :)))

XXX: Меня всегда умиляла фраза: Более подробную информацию по работе с кешом nginx ищите в гугле XXX: А как гугл найдет что-то, если все пишут именно так? Ась? YYY: Жесткие конфиги. Всмысле пиздец говноконфиги.

Вот тут (ссылка copi.st/UBxU) более простой способ "выключить кэш" Например, так

  location / {
      if (условие) {
          set $do_not_cache 1;
      }
  
      proxy_cache_bypass $do_not_cache; # выдавать мимо кэша, если $do_not_cache имеет непустое значение
  }

Ещё можно выключить через директиву proxy_no_cache

Ваш комментарий. Вики-синтаксис разрешён:
107 +11 = 
 
practice/nginx/cache.txt · Последнее изменение: 2022/08/31 14:53 — 127.0.0.1
Gentoo Linux Gentoo Linux Driven by DokuWiki