Контакты

Настройка кэширования статики с помощью nginx в Debian. Настройка сжатия и кэширования на хостинге с Nginx и Apache Кэширование centos 6 gzip nginx

Wordpress далеко не самая производительная платформа для ведения блогов, и крупные сайты, как правило, используют кэширование для ускроения его работы. Для wordpress, есть много популярных дополнений реализующих кэширование, но все они на мой взгляд довольно осложненные, и, как правило, требуют либо установки дополнительного программного обеспечения, такого как, например, Varnish или memcached, либо перекладывают кэширование на плечи PHP который тоже производительным не назовешь. В этом посте я расскажу как настроить кэширование wordpress средствами nginx , без установки дополнительного ПО.

В nginx есть FastCGI модуль который предоставляет директивы, позволяющие кэшировать ответ от fastcgi. Использование данного модуля избавляет нас от необходимости использовать сторонние средства кэширования. Модуль так же позволяет нам не кэшировать часть ресурсов опираясь на различные параметры запроса, такие как, например: тип (GET, POST), куки, адрес страницы и другие. Сам модуль умеет исключительно добавлять в кэш, но не умеет его очищать или удалять отдельные записи из него. Без очистки кэша при добавлении, редактировании и добавлении комментария к посту кэш не будет обновляться, и сделанные изменения будут видны только с большой задержкой, поэтому для очистки кэша мы будем использовать сторонний nginx модуль - nginx_cache_purge .

Настройка nginx

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

nginx -V 2>& 1 | grep -o nginx-cache-purge

Если после выполнения команды вы видите nginx-cache-purge , то значит можно продолжать. Если после выполнения команды ничего не появилось, то у вас вероятно какой-то из старый дистрибутивов ubuntu, в котором nginx собран без поддержки этого модуля. В данном случае необходимо переустановить nginx из стороннего ppa:

sudo add-apt-repository ppa:rtcamp/nginx sudo apt-get update sudo apt-get remove nginx* sudo apt-get install nginx-custom

Настроим nginx. Откроем файл с настройками виртуального хоста, и приведем его к примерно такому содержимому:

fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m ; fastcgi_cache_key " $scheme$request_method$host$request_uri" ; fastcgi_cache_use_stale error timeout invalid_header http_500 ; fastcgi_ignore_headers Cache-Control Expires Set-Cookie ; # Upstream to abstract backend connection(s) for php upstream php { server unix:/var/run/php5-fpm.sock fail_timeout=0 ; } server { listen 80 ; server_name .example.com ; root /var/www/example.com/html ; index index.php ; error_log /var/www/example.com/log/error.log ; access_log /var/www/example.com/log/access.log ; set $skip_cache 0 ; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1 ; } if ($query_string != "") { set $skip_cache 1 ; } # Don"t cache uris containing the following segments if ($request_uri ~ * "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { set $skip_cache 1 ; } # Don"t use the cache for logged in users or recent commenters if ($http_cookie ~ * "comment_author|wordpress_+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1 ; } location / { try_files $uri $uri/ /index.php? $args ; } location ~ \.php$ { try_files $uri = 404 ; include fastcgi_params ; fastcgi_pass php ; fastcgi_cache_bypass $skip_cache ; fastcgi_no_cache $skip_cache ; fastcgi_cache WORDPRESS ; fastcgi_cache_valid 60m ; } location ~ /purge(/.*) { allow 127 .0.0.1 ; deny all ; fastcgi_cache_purge WORDPRESS " $scheme$request_method$host$1" ; } location ~ * ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf) $ { access_log off ; log_not_found off ; expires max ; } location ~ /\. { deny all ; access_log off ; log_not_found off ; } location = /favicon.ico { log_not_found off ; access_log off ; } location = /robots.txt { allow all ; log_not_found off ; access_log off ; } # Deny access to uploads that aren’t images, videos, music, etc. location ~ * ^/wp-content/uploads/.*.(html|htm|shtml|php|js|swf) $ { deny all ; } # Deny public access to wp-config.php location ~ * wp-config.php { deny all ; } }

Разумеется, параметры root , server_name , access_log , error_log необходимо исправить согласно тому, как у вас все настроенно. В строке fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; мы говорим nginx, что хранить кэш нужно в директории /var/run/nginx-cache/ , зону памяти называем WORDPRESS , максимальный размер кэша устанавливаем в 100 мегабайт и таймер сброса из-за неактивности устанавливаем в 60 минут. Приятным бонусом подобной конфигурации является то, что если по каким-то причинам наш PHP бекэнд перестает работать, nginx продолжит отдавать закэшированные страницы.

Настройка Wordpress

Сам nginx не знает, когда нужно очищать кэш, поэтому необходимо установить дополнение для wordpress, которое будет автоматически очищать кэш после изменений. Ставим дополнение nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

И если все хорошо - перезагружаем его:

systemctl reload nginx

Заходим на любую страницу, и проверяем что nginx добавил её в кэш:

ls -la /var/run/nginx-cache

Дополнительно: помещаем кэш nginx в ramdisk (tmpfs)

Сейчас у нас кэширование настроено, но кэш хранится на жестком диске, что не является хорошим решение. Оптимальнее будет смонтировать директорию с кэшем nginx в память. Для этого откроем /etc/fstab , и добавим туда:

tmpfs /var/run/nginx-cache tmpfs nodev,nosuid,size= 110M 0 0

Если в настройках nginx вы указали больший размер кэша, то параметр size необходимо изменить в соответствии с указанным размером кэша, плюс небольшой запас.
Сразу смонтируем директорию в память:

Теперь при каждой загрузке системы, директория /var/run/nginx-cache будет помещаться в память, что должно уменьшить время отдачи страницы.

Заключение

Не стоит рассчитывать на данный способ как на панацею. Интерпретатор PHP как я уже выше писал, нельзя назвать быстрым, да и сам Wordpress довольно большой и "тяжелый". Если страницы нет в кэше, или она редко запрашивается, то nginx всё равно сначала будет обращаться к не самому производительному бекэнду. Однако в целом, кэширование даст возможность вашему серверу немного расслабиться на генерации популярных постов, и в моменты публикации нового поста.

Это далеко не единственный способ ускорить ваш wordpress блог. Существует ещё масса других техник, о которых я напишу позже.

HTTP заголовок Expires наряду с несколькими другими заголовками, такими как Cache-Control позволяет управлять кэшем, тем самым сообщая, как долго запрашиваемый контент будет актуален. После того как «время жизни» истекает, кэш перестает быть актуальным, и возникает необходимость запрашивать исходный ресурс, чтобы узнать были ли изменения в контенте. Заголовок Expires является стандартным заголовком, регламентированным в протоколе HTTP, и поддерживается практически любым кэшом. Что касается заголовка Cache-Control, то он был введен в HTTP/1.1 , позволив тем самым предоставить возможность веб-мастерам осуществлять больший контроль над контентом, а так же решить ограничения связанные с Expires. Чтобы использовать Cache-control эффективно, рекомендуется указывать время, по истечении которого кэш перестает быть актуальным.

В данном посту мы рассмотрим примеры настройки параметра expires в Nginx. Для начала попробуем в настройках выставить максимальный возможный срок хранения кэша.
Ставим кэш на максимальный срок

Server { ... location ~* ^.+\.(jpg|gif|png)$ { expires max; } ... }

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

Server { ... location ~* ^.+\.(jpg|gif|png)$ { expires 7d; } ... }

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

Server { ... location ~* ^.+\.(jpg|gif|png)$ { expires modified 3d; } ... }

Используя такой метод, в результате мы получаем время кэша, которое будет зависеть от времени последней модификации файла. С момента последней модификации, браузер будет запрашивать файл через 3 дня. Для некоторых задач такой способ кэширования может оказаться более удобным.
Можно так же отключить кэширование файлов браузером, для этого выставляем значение параметра в off.
Отключаем кэширование файлов в браузере

Server { ... location ~* ^.+\.(jpg|gif|png)$ { expires off; } ... }

Заданное таким образом значение полностью отключает действие Сache-control. Используя кэширование, клиентская часть избегает необходимости скачивать контент целиком, т.к. он уже имеет локальные копии файлов. Выставлять время кэширования нужно осмысленно, без лишнего фанатизма, очень долгий кэш может быть не всегда рационален, если данные у вас меняются довольно динамично.

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

Используется при больших нагрузках. Кэширование позволяет быстрее отдавать контент при втором и последующих обращениях к сайту. В блоге Nginx про кэширование .

Также кэширующие сервера легко кластеризуются

Чтобы кэширование nginx работало корректно в конфигурационном файле nginx.conf определяется путь к каталогу, в который будут складываться закэшированные на стороне сервера данные и задается его размер.

Рассматривается серверное кэширование и использование Nginx как хранилища. задается проще.

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

Кэширующий веб-сервер дает снижение нагрузки. Страница, один раз сгенерированная, сохраняется в кэш и отдается клиентам из него пока не истечет установленный TTL (time to live). Когда он истечет страница вновь будет сгенерирована и загружена в кэш — это требуется для того, чтобы посетитель сайта получал актуальную информацию.

Nginx кэширование: настройка

В примере закэшированные данные будут складываться на сервере 123.123.123.123 в каталог /var/cache/nginx . Максимальный размер файлов в кэше — 128 Мб, если этого буфера будет не хватать самые редко запрашиваемые данные будут вытесняться

mcedit /etc/nginx/nginx.conf

http {
proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=all:128m;
}

Каталог /var/nginx/cache нужно создать

mkdir -p /var/nginx/cache

Настройка виртуального хоста

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

server {
listen *:80;

server_name example.com;
access_log /var/log/nginx/access.log;

location / {

proxy_pass http://124.124.124.124:80/;
proxy_set_header Host $host;
proxy_buffering on;
proxy_cache all;
proxy_cache_valid any 30m;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;

}

В конфигурационном файле указано, что кэшировать нужно все содержимое, TTL установлен в 30 минут.

Виртуальный хост активируется

На основном Nginx сервере с адресом 124.124.124.124:

Никаких изменений здесь вносить не требуется — можно при необходимости запустить веб-сервер на альтернативном порту.

mcedit /etc/nginx/sites-availible/example.com

server {
listen *:80;
server_name example.com;
proxy_read_timeout 200s;
access_log off;

root /var/www/sites/example.com/;

location / {
proxy_pass http://127.0.0.1:8080;
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_set_header X-Forwarded-Proto $scheme;

}

}

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled

Конфигурация может быть любой: Nginx + PHP-FPM или как в примере.

Добавляем файл index.php для того чтобы проверить кэширование

mcedit /var/www/sites/example.com/index.php

echo «Works!»;

?>

Теперь можно обратиться к сайту через браузер, «Works!» будет говорить о том, что запросы успешно перенаправляются.

На кэширующем Nginx сервере с адресом 123.123.123.123:

Теперь можно проверить появилось ли что-либо в каталоге, выделенном под хранилище данных

На не слишком загруженных сайтах благодаря браузерному кэшированию и предварительному сжатию данных можно и вовсе обойтись без плагинов кэширования. Однако в этом посте даны директивы, которые актуальны только для хостинга, на котором работает HTTP-сервер Apache. Некоторые хостеры ради экономии серверных ресурсов отключают Apache или вовсе не устанавливают его, предпочитая настраивать только менее прожорливый веб-сервер Nginx. Давайте посмотрим, как можно настроить предварительное сжатие и браузерное кэширование, если на вашем хостинге работает только Nginx.

1. Предварительное сжатие
Перед тем, как отдать содержимое страниц в браузер посетителя, можно его сжать. Сжатие уменьшает размер передаваемых файлов (иногда в несколько раз), что приводит к увеличению скорости загрузки страниц и уменьшению исходящего трафика. Сжимать нужно только файлы, содержащие текстовую часть - текст, HTML, PHP, JS, XML, и прочие подобные. Текст хорошо сжимается даже при низком уровне компрессии, объем передаваемых фалов уменьшается на 50-80%. Конечно, файлы небольшие, всего десятки килобайт, но если учесть, что таких фалов тысячи, и загружаются они тысячами посетителей каждый день, то, как говорят, с миру по нитке - нищему на воротник, экономия получается существенная.

1-1. Предварительное сжатие / Apache
Для тех, у кого установлен Apache, нужно узнать у хостера, какие специальные модули, реализующие его, установлены - mod_pagespeed или mod_deflate? Обычно в Apache 2x устанавливают mod_deflate. Есть еще mod_gzip, но его устанавливали в предыдущих версиях, так что его встретить маловероятно.

Если установлен модуль mod_pagespeed, то в файл.htaccess, находящийся в корне вашего сайта, нужно вставить:


ModPagespeed on
# using commands,filters etc

Если установлен модуль mod_deflate, то то в файл.htaccess, находящийся в корне вашего сайта, нужно вставить:


AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript


В данном случае сжатию подвергаются все текстовые файлы - txt, html, xml, xhtml, css, js.

Или в httpd.conf находящийся в /usr/local/ets/Apache22/:


AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css

BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0 no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html


После чего обязательно нужно перезапустить апач

/usr/local/etc/rc.d/apache22 restart

1-2. Предварительное сжатие / Nginx
Если хостинг работает под управлением Nginx, то директивы будут выглядеть иначе. В файл.htaccess, находящийся в корне вашего сайта, нужно вставить:

server {
gzip on;
gzip_types text/html text/css application/x-javascript text/plain text/xml image/x-icon;
}

1-3. Предварительное сжатие / Скрипт
Бывает так, что сервер, обеспечивающий работу вашего блога, не поддерживает mod_deflate или mod_gzip. В этом случае можно прибегнуть к универсальному скрипту, который работает и на Apache, и на Nginx.

В основном файле используемого вами движка, в самое его начало, первой строкой нужно вставить:

function isClientSupportGzip() {
if (headers_sent() || connection_aborted()) return false;
if (stripos(getenv("HTTP_ACCEPT_ENCODING"), "gzip") === false) return false;
if (stripos(getenv("HTTP_USER_AGENT"), "konqueror") !== false) return false;
return true;
}

If (isClientSupportGzip()) {
ob_start("ob_gzhandler");
}
else {
ob_start();
}


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

2. Браузерное кэширование
Наряду со сжатием можно давать браузеру команду использовать кэшированную копию. Зачем каждый раз качать файлы с сайта, если они не с момента последнего посещения не изменились? Лучше отслеживать изменения файлов, и скачивать только те, которые им подверглись, а те, что остались с последнего захода на сайт не измененными, брать их кэша. Этот способ позволяет существенно сократить трафик между браузером посетителя и хостингом сайта, что приводит к сокращению времени загрузки страниц. Особенно заметен прирост в скорости на страницах с картинками. Действительно, картинки меняются на сайте очень редко, и зачем их каждый раз закачивать, есди они уже есть в кэше браузера?

2-1. Браузерное кэширование / установки заголовков / Apache
Apache обеспечивает браузерное кэширование с помощью модулей mod_expires и mod_headers: mod_expires определяет время актуальности кэшированных данных, а mod_headers - их публичную доступность. Совместная работа приводит к гибкой проверке данных перед скачиванием: браузер получает специальные заголовки, по ним определяет, устарели ли данные, которые находятся у него в кэше с момента последнего посещения страницы, и если они устарели, то обновляет их, закачивания новые версии файлов, а если не устарели, то отображает файлы из своего кэша, не скачивая с сервера.

Если у вас работает Apache, для установки заголовков Expires добавьте в файл.htaccess:


ExpiresActive On
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"


В данном случае актуальность кэша для разных фалов указана в секундах.

Если у вас работает Apache, для установки для установки заголовка Cache-control добавьте в файл.htaccess:






Header set Cache-Control "public"


Header set Cache-Control "private"


Header set Cache-Control "private, must-revalidate"


В данном случае проверяется актуальность в кэше файлов ico, jpg, jpeg, png, gif, swf, css, js, html, xhtml, php.

2-2. Браузерное кэширование / Nginx
Если у вас нет Apache, но есть Nginx, то для того, чтобы указать браузеру брать закэшированные данные, нужно вставить в конфиг nginx следующие строки:

location ~* \.(jpg|png|gif|jpeg|css|js)$ {
expires 24h;
}


В данном случае актуальность кэша 24 часа, а типы проверяемых файлов указаны перечислением - jpg, png, gif, jpeg, css, js.

Вот собственно и все основы, удачного ускорения ваших сайтов! ;)

Не всегда бывает достаточно внесения правок в.htaccess файл для включения жизненно-необходимых для быстрой работы сайта функций, как сжатие и кеширование браузером. Особенно если у вас сервер на NGINX.

Приведу пример для включения этого функционала.

Сразу сделаем оговорку. Вы должны иметь доступ к файл nginx.conf из каталога /usr/local/nginx/conf , или /etc/nginx , или /usr/local/etc/nginx , в зависимости от ОС. Это подразумевает что у Вас выделенный или виртуальный сервер. На обычных хостингах может помочь только обращение в техническую поддержку.

Сжатие GZIP для сайта на NGINX

Выглядит это следующим образом

Http { #buffer_size, разные include и прочие общие настройки gzip on; gzip_min_length 1000; gzip_proxied any; gzip_disable "MSIE \.(?!.*SV1)"; gzip_types text/plain text/xml application/xml application/x-javascript text/javascript text/css text/json; gzip_comp_level 1; server { #настройки каждого из сайтов на сервере } }

Таким образом для всех сайтов на сервере включается сжатие.

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

Для кеширования необходимы следующие изменения:

Location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 30d; #Остальные директивы }

Таким образом решается эта простая проблема, которая становится порой серьезной головной болью вебмастеров, плохо знакомых с работой системного администратора Linux.

Понравилась статья? Поделитесь ей