Как настроить кэширование FastCGI с помощью Nginx на вашем VPS
Прелюдия
Nginx включает в себя модуль FastCGI с директивами для кэширования динамического контента, который обслуживается из серверной части PHP. Настройка этого устраняет необходимость в дополнительных решениях для кэширования страниц, таких как обратные прокси-серверы (например, Varnish) или плагины для конкретных приложений. Контент также можно исключить из кэширования на основе метода запроса, URL-адреса, файлов cookie или любых других переменных сервера.
Включение кэширования FastCGI на вашем VPS
В этой статье предполагается, что вы уже установили и настроили файл конфигурации виртуального хоста, для которого необходимо включить кэширование.
nano /etc/nginx/sites-enabled/vhost
Добавьте следующие строки в начало файла вне директивы server { }:
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
Директива \fastcgi_cache_path указывает расположение кеша (/etc/nginx/cache), его размер (100 м), имя зоны памяти (MYAPP), уровни подкаталогов и таймер inactive\\.
Расположение может быть где угодно на жестком диске; однако размер должен быть меньше, чем RAM + Swap вашей капли, иначе вы получите сообщение об ошибке «Не удается выделить память». Мы рассмотрим параметр «уровни» в разделе очистки — если доступ к кешу не осуществляется в течение определенного периода времени, указанного параметром «неактивный» (здесь 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. Также можно указать другие коды ответов.
Проведите тест конфигурации
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 на вашем VPS
Создайте файл PHP, который выводит временную метку UNIX.
/usr/share/nginx/html/time.php
Вставлять
<?php
echo time();
?>
Запросите этот файл несколько раз с помощью curl или веб-браузера.
root@droplet:~# curl http://localhost/time.php;echo
1382986152
root@droplet:~# curl http://localhost/time.php;echo
1382986152
root@droplet:~# curl http://localhost/time.php;echo
1382986152
Если кэширование работает правильно, вы должны увидеть одну и ту же метку времени для всех запросов, так как ответ кэшируется.
Сделайте рекурсивный список местоположения кеша, чтобы найти кеш этого запроса.
root@droplet:~# 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 b777c8adab3ec92cd43756226caf618e
Соглашение об именах будет объяснено в разделе очистки.
Мы также можем заставить Nginx добавить к ответу заголовок \X-Cache, указывающий, был ли кеш пропущен или попал.
Добавьте следующее над директивой server { }:
add_header X-Cache $upstream_cache_status;
Перезагрузите службу Nginx и выполните подробный запрос с помощью curl, чтобы увидеть новый заголовок.
root@droplet:~# 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;
Директива \fasctcgi_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. Следовательно, первый уровень каталога будет иметь имя с символом 1 из последней строки этой MD5, которая является e; второй уровень будет иметь последние 2 символов после первого уровня, т. е. 18. Следовательно, вся структура каталогов этого кэша выглядит следующим образом:
/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e
На основе этого формата именования кеша вы можете разработать сценарий очистки на своем любимом языке. Для этого урока я предоставлю простой PHP-скрипт, который очищает кеш URL-адреса __POST__ed.
/usr/share/nginx/html/purge.php
Вставлять
<?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 в зависимости от того, был ли очищен кеш или нет. Обязательно исключите этот скрипт из кэша, а также ограничьте доступ.
Представлено: Джесин А