Настройка кеширования в веб-сервере nginx
Читать полностью!!
Для чего это нужно?
Во-первых одно из основных преимуществ nginx[1] - это очень быстрая отдача статического контента. Т.к. основной объем трафика занимает статика(это картинки, видеоклипы, flash-файлы, таблицы стилей css, и JavaScript), то имеет смысл использовать бесплатный способ ускорения - кеширование на стороне клиента и на промежуточных proxy-серверах (наподобие squid).
Как реализуется?
Очень просто! Для начала необходимо найти конфигурационный файл, обычно на *nix системах он находиться в /usr/local/nginx/conf/nginx.conf (как правило он там находиться если вы ставили его из исходников), в пакетных дистрибутивах Linux (Debian, Ubuntu, Fedora, SUSE etc) он вероятнее всего будет находиться в /etc/nginx/nginx.conf (в том случае если сайты описаны прямо в нем ) или /etc/nginx/sites-avaible/sitename.conf.
В секции server мы добавляем следующий локейшн(куда именно размещать значения не имеет ну лучше в конце чтобы не перекрывал другие правила):
#!Статический контент! location ~* \.(jpg|jpeg|gif|png|swf|tiff|swf|flv)$ { root $webroot; #Кеширум картинки месяца на 4 expires 4M; #Кешируем везде (и на прокси и на клиентах) add_header Cache-Control public; }
в примере осуществляется кеширование на стороне как клиента так и промежуточных серверов. переменная $webroot указывает, где находиться папка с файлами moodle, например:
set $webroot '/var/www/moodle'; root $webroot;
эту запись лучше разместить в начале; еще можно воспользоваться сжатием для тех браузеров которые его поддерживают, имеет смысл только при отдаче несжатого контента - css, js, ico :
location ~* \.(css|js|ico) { # разрешаем отдавать вместо несжатого файла предварительно # сжатый с постфиксом ".gz", если такой есть gzip_static on; #запрещаем сжатие файлов CSS и JS для проблемных браузеров gzip_disable Firefox/([0-2]\.|3\.0); gzip_disable Chrome/2; gzip_disable Safari; #Кешируем месяца на 2 expires 2M; #Кешируем только на клиентах (ибо сжатое) add_header Cache-Control private; }
Работать эта конструкция будет только при наличии установленного модуля gzip_static в nginx, размещать опять таки лучше в конце.
Теперь чтобы не закешировать лишнее у всего остального контента необходимо запретить кеширование, для этого в начале секции server вставляем:
#Просрочиваем кеш expires epoch;
Теперь даже если данные закешируются, браузер все равно будет их запрашивать т.к. дата просрочена.
Все было бы отлично если бы не механизм отдачи файлов в moodle - все файлы отдаются через скрипт file.php и соответственно под предыдущие регэкспы не попадет, для решения этой проблемы воспользуемся следующим кодом:
#Файлы запрашиваемые через мудл (кеширование включено и настроено) location ~ \/file\.php\/.*$ { root $webroot; fastcgi_pass unix:/tmp/fastcgi/www-data/php5/socket; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $webroot$fastcgi_script_name; fastcgi_buffer_size 16K; fastcgi_buffers 4 128K; fastcgi_connect_timeout 60; #fastcgi_cache wholepage; #fastcgi_cache_path /var/cache/nginx levels= keys_zone=wholepage:50m; fastcgi_cache_valid 200 301 302 304 5m; fastcgi_cache_key \ "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri"; fastcgi_ignore_headers "Cache-Control" "Expires"; include fastcgi_params; #Кешируем отданнный файл месяца на 4 expires 4M; #Кешируем только на клиентах. add_header Cache-Control private; break; }
Этот обработчик необходимо вставить перед основным обработчиком php, выглядит он примерно так:
#Исполняемый код location ~ \.php$ { root $webroot; fastcgi_pass unix:/tmp/fastcgi/www-data/php5/socket; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $webroot$fastcgi_script_name; fastcgi_cache off; fastcgi_connect_timeout 60; fastcgi_hide_header "Cache-Control"; fastcgi_hide_header "Expires"; fastcgi_ignore_headers "Cache-Control" "Expires"; include fastcgi_params; }
Примечание: в качестве механизма передачи между nginx и php-cgi предпочтительнее использовать сокеты нежели петлевой интерфейс (loopback). Это связанно с тем что loopback использует TCP и для того чтобы общаться приходиться постоянно инкапсулировать-декапсулировать информацию, в сокетах обмен идет напрямую. Обработчик в случае сокетов выглядит так:
location ~ \.php$ { root $webroot; fastcgi_pass unix:/tmp/fastcgi/www-data/php5/socket; ... }
в случае с loopback
location ~ \.php$ { root $webroot; fastcgi_pass 127.0.0.1:9000; ... }