Лично мной настройка кэширования статики с помощью nginx в Debian задумывалась ради ускорения выдачи статического контента сайта на wordpress. Проблема возникла в том, что при использовании многосайтовой версии wordpress файлы хранятся в директории с длинным путём, при этом используется сокращение адреса за счет правил mod_rewrite. Для того, чтобы nginx выдавал статику, использовалась директива location с указанием расширений статических файлов и путь до директории со статикой:

Location ~* \.(html|jpeg|jpg|gif|png|css|js|pdf|txt|tar)$ { root /path/to/site/; }

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

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

Использовались ОС Debian 7.0, nginx 1.2.1. Предварительно следует обновить Debian .

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

Так как в основном конфиге /etc/nginx/nginx.conf имеем строку include /etc/nginx/conf.d/*.conf , то создаём отдельный файл /etc/nginx/conf.d/cache.conf с базовыми настройками кэша:

Proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:100m inactive=120m max_size=500M; proxy_cache_min_uses 1;

Разберём поэлементно первую строку, начинающуюся с proxy_cache_path . Таких строк может быть несколько, следовательно может быть несколько кэшей со своими параметрами и именами. Итак:

/var/cache/nginx - путь до директории с кэшем.

levels=1:2 - уровни директорий с кэшем. Уровни вложенности задаются через двоеточие, цифрами задаётся длинна имени директории. 1:2 говорит о том, что в директории с кэшем будут созданы директории длинной в одну шестнадцатеричную цифру (от 0 до f) в каждой из которых будут созданы директории с именами состоящими из двух шестнадцатеричных цифр.

keys_zone=static_cache:100m - задаётся имя кэша (static_cache ) и его базовый размер в мегабайтах.

inactive=120m - время отсутствия запросов к элементу кэша, после которого он удаляется из кэша. В минутах. После этого, при запросе к тому же файлу, произойдёт запрос к бэкенду и файл снова попадёт в кэш.

max_size=500M - максимальный размер кэша в мегабайтах.

Вторая строка, как было выяснено экспериментально, также необходима для работы кэша nginx:

proxy_cache_min_uses 1; - указывает после какого количества запросов к файлу он попадёт в кэш.

Не забудьте создать директорию для кэша и задать для нее владельца от имени которого работает nginx в Debian:

Mkdir /var/cache/nginx chown www-data:www-data /var/cache/nginx

Затем в файле описания сайта в директории /etc/nginx/sites-available прописываем примерно следующее:

Location ~* ^.+.(html|jpg|jpeg|gif|css|png|js|ico|gz)$ { expires 60d; proxy_pass http://backend; proxy_redirect off; 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_cache static_cache; proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri"; proxy_cache_valid 1d; }

В данном случае мы запросы также перенаправляем на бэкенд, но при этом кэшируем их на сутки. Нас интересуют следующие параметры:

proxy_cache static_cache; - указываем какой кэш использовать.

proxy_cache_valid 1d; - позволяет задать время кэширования для разных кодов ответа. По умолчанию кэшируются только ответы с кодами 200, 301 и 302.

proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri"; - эта строка самая интересная. Она позволяет настроить по каким признакам считать, что следует кэшировать запросы отдельно. К примеру, значение в файле кэша nginx может выглядеть следующим образом:

GET|||droid.gesu.su|/wp-content/plugins/addthis/css/output.css?ver=3.5.1

Видно, что в данном случае

$request_method = GET
$host = droid.gesu.su
$request_uri = /wp-content/plugins/addthis/css/output.css?ver=3.5.1

То есть при использовании другого метода запроса файл нужно кэшировать отдельно. То же для одинакового имени для разных доменных имён или разных имён файлов для одного домена.

$http_if_modified_since и $http_if_none_match - позволяют не выдавать страницы с ответом “304 Not Modified” или пустые страницы. В нашем случае, это, скорее всего, не актуально, так как мы выдаём статический контент, который редко изменяется.

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

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

Кэшируются изображения стили CSS и Javascript. Кэширование браузера Nginx реализуется за счет добавления заголовка Cache-control .

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

Кэширование браузера Nginx

В конфигурационном файле Nginx кэширование JS/CSS включается следующим образом (добавлены и другие расширения — на практике лучше кэшировать их все):

server {

location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ {
expires max;
root /home/website/example.com/;
}

}

expires max говорит о том, что TTL устанавливается в бесконечность и в случае если файлы на сервере будут изменены клиент об этом никогда не узнает поскольку повторный запрос отправлен не будет.

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

Обычно в конфиге сервера устанавливается именно значение expires max, затем в приложении при подключении css и js файлов определяются их версии, которые должны меняться каждый раз при обновлении содержимого.

Указание заголовков, задающих кэширование на уровне приложения

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

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

Дополнительный заголовок HTTP Expires указывает дату и время, когда браузер должен обновить кэш (заголовки можно использовать совместно, Expires при использовании обоих заголовков имеет меньшее значение):

Оба заголовка могут быть заданы в программном коде на уровне приложения.

Включение кэширования в РНР

Большая часть веб-проектов пишутся на языке РНР, в РНР HTTP заголовки Cache-control и Expires задаются следующим образом:


Close