Настройка кеширования в веб-сервере nginx

Материал из MoodleDocs
Перейти к:навигация, поиск

Читать полностью!!


Для чего это нужно?

Во-первых одно из основных преимуществ 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;
    ...
   }

Ссылки