Компьютерная грамотность, помощь и ремонт

Сжатие и кеширование браузером для NGINX. Настройка кэширования статики с помощью nginx в Debian Также кэширующие сервера легко кластеризуются

|

Nginx включает в себя модуль FastCGI, который позволяет использовать директивы для кэширования динамического контента в интерфейсе PHP. FastCGI устраняет необходимость искать дополнительные решения для кэширования страниц (например, обратные прокси или специальные плагины приложений). Контент также может быть исключен из кэширования на основе метода запроса, URL, cookies или любой другой переменной сервера.

Активация кэширования FastCGI

Чтобы следовать данному руководству, нужно заранее . Также нужно отредактировать конфигурационный файл виртуального хоста:

nano /etc/nginx/sites-enabled/vhost

Внесите следующие строки в начало файла вне директивы server { } :

Директива fastcgi_cache_path задает путь к кэшу (/etc/nginx/cache), указывает его размер (100m), имя зоны памяти (MYAPP), уровни подкаталогов и таймер inactive.

Кэш можно размещать в любой удобной точке жесткого диска. Максимальный размер кеша не должен превышать RAM сервера+размер swap-файла; в противном случае будет выведена ошибка Cannot allocate memory. Если кэш не был использован в течение конкретного периода времени, указанного с помощью опции «inactive» ​​(в данном случае это 60 минут), то Nginx удаляет его.

Директива fastcgi_cache_key указывает способ хеширования имен файлов. Согласно данным настройкам, Nginx будет шифровать файлы с помощью MD5.

Теперь можно перейти к директиве location, которая передает PHP-запросы модулю php5-fpm. В location ~ .php$ { } внесите следующие строки:

fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;

Директива fastcgi_cache ссылается на зону памяти, которая уже была указана в директиве fastcgi_cache_path.

По умолчанию Nginx хранит кешированные объекты в течение времени, указанного с помощью одного из этих заголовков:

X-Accel-Expires
Expires
Cache-Control.

Директива fastcgi_cache_valid указывает срок хранения кэша по умолчанию, если ни одного из этих заголовков нет. Согласно установленному значению кэшируются только ответы с кодом состояния 200 (конечно, можно указать и другие коды состояния).

Проверьте настройки FastCGI

service nginx configtest

Затем перезапустите Nginx, если с настройками все в порядке.

service nginx reload

На данном этапе файл vhost должен иметь следующий вид:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
root /usr/share/nginx/html;
index index.php index.html index.htm;
server_name example.com;
location / {
try_files $uri $uri/ /index.html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;
}
}

Теперь нужно проверить, работает ли кеширование.

Проверка кэширования FastCGI

Создайте PHP-файл, который выводит метку времени UNIX.

/usr/share/nginx/html/time.php

Внесите в файл:

echo time();
?>

Затем несколько раз запросите данный файл через curl или веб-браузер.

root@server:~# curl http://localhost/time.php;echo
1382986152

1382986152
root@server:~# curl http://localhost/time.php;echo
1382986152

Если кеширование выполняется должным образом, временная отметка всех запросов будет совпадать (поскольку ответ был кеширован).

Чтобы найти кэш этого запроса, нужно выполнить обратную запись кэша

root@server:~# ls -lR /etc/nginx/cache/
/etc/nginx/cache/:
total 0
drwx------ 3 www-data www-data 60 Oct 28 18:53 e
/etc/nginx/cache/e:
total 0
drwx------ 2 www-data www-data 60 Oct 28 18:53 18
/etc/nginx/cache/e/18:
total 4
-rw------- 1 www-data www-data 117 Oct 28 18:53

Можно также добавить заголовок X-Cache, который укажет, что данный запрос был обработан из кеша (X-Cache HIT) или напрямую (X-Cache MISS).

Над директивой server { } внесите:

add_header X-Cache $upstream_cache_status;

Перезапустите сервис Nginx и выполните подробный запрос с помощью curl, чтобы увидеть новый заголовок.

root@server:~# curl -v http://localhost/time.php
* About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /time.php HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
>
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 29 Oct 2013 11:24:04 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Cache: HIT
<
* Connection #0 to host localhost left intact
1383045828* Closing connection #0

Исключения кэширования

Некоторый динамический контент (например, страницы запроса аутентификации) кешировать не нужно. Такой контент можно исключить из кеширования при помощи переменных request_uri, request_method и http_cookie.

Ниже приведен пример настроек, который можно использовать в контексте server{ }.

#Cache everything by default
set $no_cache 0;
#Don"t cache POST requests
if ($request_method = POST)
{
set $no_cache 1;
}
#Don"t cache if the URL contains a query string
if ($query_string != "")
{
set $no_cache 1;
}
#Don"t cache the following URLs
if ($request_uri ~* "/(administrator/|login.php)")
{
set $no_cache 1;
}
#Don"t cache if there is a cookie called PHPSESSID
if ($http_cookie = "PHPSESSID")
{
set $no_cache 1;
}

Чтобы применить переменную $no_cache в соответствующие директивы, поместите следующие строки в location ~ .php$ { }

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;

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

Очистка кэша

Соглашение об именах кэша основывается на переменных, которые были применены в директиве fastcgi_cache_key.

fastcgi_cache_key "$scheme$request_method$host$request_uri";

Согласно этим переменным, при запросе http://localhost/time.php будут выведены следующие значения:

fastcgi_cache_key "httpGETlocalhost/time.php";

После хеширования этой строки в MD5 получилось бы следующее:

b777c8adab3ec92cd43756226caf618e

Это сформирует имя файла кэша в соотношении с подкаталогами, указанными в levels=1:2. Таким образом, первый уровень каталога в этой строке MD5 будет обозначен последним символом строки (в данном случае это символ е). Второму уровню принадлежат следующие после первого уровня 2 символа (18). Таким образом, вся структура каталогов этой кэш-зоны будет выглядеть так:

/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e

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

/usr/share/nginx/html/purge.php

Внесите в него:

$cache_path = "/etc/nginx/cache/";
$url = parse_url($_POST["url"]);
if(!$url)
{
echo "Invalid URL entered";
die();
}
$scheme = $url["scheme"];
$host = $url["host"];
$requesturi = $url["path"];
$hash = md5($scheme."GET".$host.$requesturi);
var_dump(unlink($cache_path . substr($hash, -1) . "/" . substr($hash,-3,2) . "/" . $hash));
?>

Отправьте POST-запрос на этот файл с URL, который нужно очистить.

curl -d "url=http://www.example.com/time.php" http://localhost/purge.php

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

Tags: ,

We all know that the performance of applications and web sites is a critical factor in their success. The process of making your application or web site perform better, however, is not always clear. Code quality and infrastructure are of course critical, but in many cases you can make vast improvements to the end user experience of your application by focusing on some very basic application delivery techniques. One such example is by implementing and optimizing caching in your application stack. This blog post covers techniques that can help both novice and advanced users see better performance from utilizing the included in NGINX and NGINX Plus.

Overview

A content cache sits in between a client and an “origin server”, and saves copies of all the content it sees. If a client requests content that the cache has stored, it returns the content directly without contacting the origin server. This improves performance as the content cache is closer to the client, and more efficiently uses the application servers because they don’t have to do the work of generating pages from scratch each time.

There are potentially multiple caches between the web browser and the application server: the client’s browser cache, intermediary caches, content delivery networks (CDNs), and the load balancer or reverse proxy sitting in front of the application servers. Caching, even at the reverse proxy/load balancer level, can greatly improve performance.

As an example, last year I took on the task of performance tuning a website that was loading slowly. One of the first things I noticed was that it took over 1 second to generate the main home page. After some debugging, I discovered that because the page was marked as not cacheable, it was being dynamically generated in response to each request. The page itself was not changing very often and was not personalized, so this was not necessary. As an experiment, I marked the homepage to be cached for 5 seconds by the load balancer, and just doing that resulted in noticeable improvement. The time to first byte went down to a few milliseconds and the page loaded visibly faster.

NGINX is commonly deployed as a reverse proxy or load balancer in an application stack and has a full set of caching features. The next section discusses how to configure basic caching with NGINX.

How to Set Up and Configure Basic Caching

Only two directives are needed to enable basic caching: proxy_cache_path and proxy_cache . The proxy_cache_path directive sets the path and configuration of the cache, and the proxy_cache directive activates it.

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { # ... location / { proxy_cache my_cache; proxy_pass http://my_upstream; } }

The parameters to the proxy_cache_path directive define the following settings:

  • The local disk directory for the cache is called /path/to/cache/ .
  • levels sets up a two‑level directory hierarchy under /path/to/cache/ . Having a large number of files in a single directory can slow down file access, so we recommend a two‑level directory hierarchy for most deployments. If the levels parameter is not included, NGINX puts all files in the same directory.
  • keys_zone sets up a shared memory zone for storing the cache keys and metadata such as usage timers. Having a copy of the keys in memory enables NGINX to quickly determine if a request is a HIT or a MISS without having to go to disk, greatly speeding up the check. A 1‑MB zone can store data for about 8,000 keys, so the 10‑MB zone configured in the example can store data for about 80,000 keys.
  • max_size sets the upper limit of the size of the cache (to 10 gigabytes in this example). It is optional; not specifying a value allows the cache to grow to use all available disk space. When the cache size reaches the limit, a process called the cache manager removes the files that were least recently used to bring the cache size back under the limit.
  • inactive specifies how long an item can remain in the cache without being accessed. In this example, a file that has not been requested for 60 minutes is automatically deleted from the cache by the cache manager process, regardless of whether or not it has expired. The default value is 10 minutes (10m). Inactive content differs from expired content. NGINX does not automatically delete content that has expired as defined by a cache control header (Cache-Control:max-age=120 for example). Expired (stale) content is deleted only when it has not been accessed for the time specified by inactive . When expired content is accessed, NGINX refreshes it from the origin server and resets the inactive timer.
  • NGINX first writes files that are destined for the cache to a temporary storage area, and the use_temp_path=off directive instructs NGINX to write them to the same directories where they will be cached. We recommend that you set this parameter to off to avoid unnecessary copying of data between file systems. use_temp_path was introduced in NGINX version 1.7.10 and .

And finally, the proxy_cache directive activates caching of all content that matches the URL of the parent location block (in the example, / ). You can also include the proxy_cache directive in a server block; it applies to all location blocks for the server that don’t have their own proxy_cache directive.

Delivering Cached Content When the Origin is Down

location / { # ... proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; }

With this sample configuration, if NGINX receives an error , timeout , or any of the specified 5xx errors from the origin server and it has a stale version of the requested file in its cache, it delivers the stale file instead of relaying the error to the client.

Fine‑Tuning the Cache and Improving Performance

NGINX has a wealth of optional settings for fine‑tuning the performance of the cache. Here is an example that activates a few of them:

Proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { # ... location / { proxy_cache my_cache; proxy_cache_revalidate on; proxy_cache_min_uses 3; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_pass http://my_upstream; } }

These directives configure the following behavior:

  • proxy_cache_revalidate instructs NGINX to use conditional GET requests when refreshing content from the origin servers. If a client requests an item that is cached but expired as defined by the cache control headers, NGINX includes the If-Modified-Since field in the header of the GET request it sends to the origin server. This saves on bandwidth, because the server sends the full item only if it has been modified since the time recorded in the Last-Modified header attached to the file when NGINX originally cached it.
  • proxy_cache_min_uses sets the number of times an item must be requested by clients before NGINX caches it. This is useful if the cache is constantly filling up, as it ensures that only the most frequently accessed items are added to the cache. By default proxy_cache_min_uses is set to 1.
  • The updating parameter to the proxy_cache_use_stale directive, combined with enabling the proxy_cache_background_update directive, instructs NGINX to deliver stale content when clients request an item that is expired or is in the process of being updated from the origin server. All updates will be done in the background. The stale file is returned for all requests until the updated file is fully downloaded.
  • With proxy_cache_lock enabled, if multiple clients request a file that is not current in the cache (a MISS), only the first of those requests is allowed through to the origin server. The remaining requests wait for that request to be satisfied and then pull the file from the cache. Without proxy_cache_lock enabled, all requests that result in cache misses go straight to the origin server.

Splitting the Cache Across Multiple Hard Drives

If you have multiple hard drives, NGINX can be used to split the cache across them. Here is an example that splits clients evenly across two hard drives based on the request URI:

Proxy_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m max_size=10g inactive=60m use_temp_path=off; proxy_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m max_size=10g inactive=60m use_temp_path=off; split_clients $request_uri $my_cache { 50% “my_cache_hdd1”; 50% “my_cache_hdd2”; } server { # ... location / { proxy_cache $my_cache; proxy_pass http://my_upstream; } }

The two proxy_cache_path directives define two caches (my_cache_hdd1 and my_cache_hdd2) on two different hard drives. The split_clients configuration block specifies that the results from half the requests (50%) are cached in my_cache_hdd1 and the other half in my_cache_hdd2 . The hash based on the $request_uri variable (the request URI) determines which cache is used for each request, the result being that requests for a given URI are always cached in the same cache.

Please note this approach is not a replacement for a RAID hard drive setup. If there is a hard drive failure this could lead to unpredictable behavior on the system, including users seeing 500 response codes for requests that were directed to the failed hard drive. A proper RAID hard drive setup can handle hard drive failures.

Frequently Asked Questions (FAQ)

This section answers some frequently asked questions about NGINX content caching.

Can the NGINX Cache Be Instrumented?

add_header X-Cache-Status $upstream_cache_status;

This example adds an X-Cache-Status HTTP header in responses to clients. The following are the possible values for $upstream_cache_status :

How Does NGINX Determine Whether or Not to Cache Something?

By default, NGINX respects the Cache-Control headers from origin servers. It does not cache responses with Cache-Control set to Private , No-Cache , or No-Store or with Set-Cookie in the response header. NGINX only caches GET and HEAD client requests. You can override these defaults as described in the answers below.

proxy_cache_methods GET HEAD POST;

This example enables caching of POST requests.

Can NGINX Cache Dynamic Content?

Yes, provided the Cache-Control header allows for it. Caching dynamic content for even a short period of time can reduce load on origin servers and databases, which improves time to first byte, as the page does not have to be regenerated for each request.

Can I Punch a Hole Through My Cache?

location / { proxy_cache_bypass $cookie_nocache $arg_nocache; # ... }

The directive defines request types for which NGINX requests content from the origin server immediately instead of trying to find it in the cache first. This is sometimes referred to as “punching a hole” through the cache. In this example, NGINX does it for requests with a nocache cookie or argument, for example http://www.example.com/?nocache=true . NGINX can still cache the resulting response for future requests that aren’t bypassed.

What Cache Key Does NGINX Use?

The default form of the keys that NGINX generates is similar to an MD5 hash of the following NGINX variables : $scheme$proxy_host$request_uri ; the actual algorithm used is slightly more complicated.

Proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { # ... location / { proxy_cache my_cache; proxy_pass http://my_upstream; } }

For this sample configuration, the cache key for http://www.example.org/my_image.jpg is calculated as md5(“http://my_upstream:80/my_image.jpg”) .

To change the variables (or other terms) used as the basis for the key, use the proxy_cache_key directive (see also the following question).

Can I Use a Cookie as Part of My Cache Key?

Yes, the cache key can be configured to be any arbitrary value, for example:

proxy_cache_key $proxy_host$request_uri$cookie_jessionid;

This example incorporates the value of the JSESSIONID cookie into the cache key. Items with the same URI but different JSESSIONID values are cached separately as unique items.

Does NGINX Use the ETag Header?

How Does NGINX Handle the Pragma Header?

The Pragma:no-cache header is added by clients to bypass all intermediary caches and go straight to the origin server for the requested content. NGINX does not honor the Pragma header by default, but you can configure the feature with the following proxy_cache_bypass directive:

Location /images/ { proxy_cache my_cache; proxy_cache_bypass $http_pragma; # ... }

Does NGINX Support the stale-while-revalidate and stale-if-error Extensions to the Cache-Control Header?

Does NGINX Support the Vary Header?

Further Reading

There are many more ways you can customize and tune NGINX caching. To learn even more about caching with NGINX, please take a look at the following resources:

  • The ngx_http_proxy_module reference documentation contains all of the configuration options for content caching.
  • Two webinars are available on demand and step through much of the information presented in this blog post: and .
  • The NGINX Plus Admin Guide has more configuration examples and information on tuning the NGINX cache.
  • The product page contains an overview on how to configure cache purging with NGINX Plus and provides other examples of cache customization.
  • The ebook provides a thorough deep‑dive on NGINX content caching.

Лично мной настройка кэширования статики с помощью 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” или пустые страницы. В нашем случае, это, скорее всего, не актуально, так как мы выдаём статический контент, который редко изменяется.

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 блог. Существует ещё масса других техник, о которых я напишу позже.

Давно минули те старые добрые времена, когда сайты были сделаны на голом HTML и их страницы весили несколько десятков килобайт. А интернет был на dial-up.

Страницы современных сайтов весят уже несколько сотен килобайт, а частенько и несколько мегабайт. Картинки, скрипты, файлы стилей CSS - всё это непременные атрибуты нормального современного сайта и без них никак. А весит всё это «счастье» совсем не мало, и каждый раз посетители, зашедшие на ваш сайт, загружают всё это на свой компьютер. И пока загрузка не завершится, в браузере страница не откроется.

Рассмотрим метод борьбы с этой проблемой посредством вебсервера Nginx. Суть в том, что мы сделаем 2 вещи - сожмём все статические файлы (скрипты, файлы стилей) посредством gzip, и закэшируем их вместе с картинками в кэше браузера посетителя, чтобы они каждый раз не загружались с сайта, а брались прямо из кэша на компьютере посетителя сайта.

Настройка сжатия данных посредством Nginx.

Открываем файл конфигурации Nginx, расположенный по адресу /etc/nginx/nginx.conf

И в секцию http {…}, которая находится в начале файла добавляем то, чего там нет из примера ниже:

Gzip on; gzip_static on; gzip_comp_level 5; gzip_min_length 1024; gzip_proxied any; gzip_types text/plain application/xml application/x-javascript text/javascript text/css text/json;

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

В том же файле /etc/nginx/nginx.conf спускаемся ниже, находим конструкцию server для нужного сайта и дописываем туда:

Location ~* ^.+.(jpg|jpeg|gif|png|ico|css|pdf|ppt|txt|bmp|rtf|js)$ { root /var/www/user/data/www/site.ru; expires 7d;

где expires 7d - это количество дней, сколько кэш статических файлов должен храниться на компьютере пользователя. Если вы не вносите правки в css, js, файлы своего сайта и не меняете картинки, то имеет смысл этот параметр увеличить, вплоть до нескольких месяцев или даже до года.

Для наглядности приводим участок секции server из сервера, в котором Nginx был установлен стандартными средствами панели ISPmanager:

Server { server_name site.ru www.site.ru; listen 111.121.152.21; disable_symlinks if_not_owner from=$root_path; set $root_path /var/www/user/data/www/site.ru; location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { root $root_path; access_log /var/www/nginx-logs/user isp; access_log /var/www/httpd-logs/site.ru.access.log ; error_page 404 = @fallback; }

А теперь мы добавим сюда expires 7d , теперь это будет выглядеть вот так:

Server { server_name site.ru www.site.ru; listen 111.121.152.21; disable_symlinks if_not_owner from=$root_path; set $root_path /var/www/user/data/www/site.ru; location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { root $root_path; expires 7d; access_log /var/www/nginx-logs/user isp; access_log /var/www/httpd-logs/site.ru.access.log ; error_page 404 = @fallback; }

Перезагружаем Nginx командой:

Service nginx restart

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

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

Понравилась статья? Поделитесь с друзьями!
Была ли эта статья полезной?
Да
Нет
Спасибо, за Ваш отзыв!
Что-то пошло не так и Ваш голос не был учтен.
Спасибо. Ваше сообщение отправлено
Нашли в тексте ошибку?
Выделите её, нажмите Ctrl + Enter и мы всё исправим!