Преимущество FastCGI MicroCache в том, что при запросе от сервера, ответ кешируется для пользователя, и уже доступен в выделенной области на диске и в RAM.
Это большое преимущество, так как снимает нагрузку с сервера при большом количестве запросов к одной странице.
Это касается тех страниц, которые не изменяются, или изменяются редко.
Предположим большое количество пользователей одновременно просматривают главную страницу. Ответ от сервера для всех пользователей будет составлять около 2 сек до первого байта. Это связано с тем что серверу необходимо обработать данный запрос и только после - выдать его.
Чтобы уменьшить ответ до первого байта, используем FastCGI Microcache.
В начале, мой конфиг сайта выглядит примерно так:
server {
listen xx.xx.xx.xx:443 ssl http2;
server_name site.com www.site.com;
root /home/admin/web/site.com/public_html;
index index.php index.html index.htm;
ssl_certificate /home/admin/conf/web/ssl.site.com.pem;
ssl_certificate_key /home/admin/conf/web/ssl.site.com.key;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
А серверный конфиг /etc/nginx/nginx.conf так:
# Server globals
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
# Worker config
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Compression
gzip on;
gzip_vary on;
gzip_comp_level 5;
....
....
}
Для начала необходимо определить место и задать параметры хранения кэшированных запросов.
В серверный конфиг (в моем случае /etc/nginx/nginx.conf) в блок http добавляем следующую конструкцию:
fastcgi_cache_path /tmp/nginx_microcache levels=1:2 keys_zone=microcache:10m max_size=500m inactive=1h;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
Где:
fastcgi_cache_path — определяет расположение кеша на сервере. Даная директория будет очищаться при каждом перезапуске севера. То что будет хранится в данной папке, так же будет занимать место в ОЗУ.
levels=1:2 — устанавливает двухуровневую иерархию каталогов в папке /tmp/nginx_microcache
keys_zone — задать имя зоны (Вы можете указать свои предпочтения)
keys_zone=microcache:10m - 10m — размер зоны (таких зоно может быть множество для каждого сайта в отдельности если это необходимо).
max_size=500m - размер пространства которое будет занимать кеш. (Выделяется область в ОЗУ. Главное не перестараться.) Его размер должен быть меньше, чем системная оперативная память + подкачка. Иначе возможна ошибка «Не удается выделить память».
inactive — задает время, по истечении которого кеш который находиться в /tmp/nginx_microcache и в ОЗУ, к которым не обращались, в течение того времени которое указано (1 час), удаляются из кеша. (По умолчанию inactive=10m)
Далее необходимо задать ключи которые будут указывать какие запросы необходимо кешировать. Это задает директива fastcgi_cache_key.
fastcgi_cache_key — определяет какие будут кешироваться запросы.
Переменные, используемые в factcgi_cache_key
$scheme – схема запроса HTTPS или HTTP
$request_method — указывает методы запроса, такие как GET или POST.
$host – Имя сервера, соответствующего запроса
$request_uri — Полный URI запроса
Теперь что бы подключить выбранную область к нашему сайту, необходимо в его конфиг в моем случае (/home/admin/conf/web/xxxxx.xxx.nginx.ssl.conf) в блок location / добавить следующую конструкцию:
location / { #MicroCache fastcgi_cache microcache; fastcgi_cache_lock on; fastcgi_cache_valid 200 10s; fastcgi_cache_use_stale updating; # Security Header add_header X-FastCGI-Cache $upstream_cache_status; #Показывает статус кеша в блоке Header #Задаем условия, при которых ответ не будет браться из кэша. fastcgi_cache_bypass $no_cache; #Определяем переменную $no_cache fastcgi_no_cache $no_cache; #Определяем переменную $no_cache set $no_cache 0; # исключить из кэширования if ($request_method = POST) { set $no_cache 1; } if ($request_method !~ ^(GET|HEAD)$) { set $no_cache "1"; } if ($query_string != "") { set $no_cache 1; } if ($request_uri ~* "/admin") { set $no_cache 1; } # исключить из кэширования /admin } }
Директивой fastcgi_cache - задаем то же имя зоны которое определено в серверном конфиге. В моем случае microcache. (Для каждого отдельного сайта можно задавать свои зоны)
fastcgi_cache_valid - определяет время кэширования в зависимости от кода состояния HTTP (200, 301, 302). В приведенном выше примере ответы с кодом состояния 200 будут кэшироваться на 10 секунд. Вы также можете использовать период времени, например 12h(12 часов) и 7d(7 дней).
Для динамического контента, такого как, админка любой CMS, этого делать крайне не желательно.
В блоке # Security Header определены заголовки add_header X-FastCGI-Cache $upstream_cache_status; которые показывают статус запроса, закеширована страница или нет. MISS, BYPASS, EXPIRED, и HIT - чаще всего встречающиеся заголовки.
Значение HIT можно наблюдать, когда страница получена из кэша. Если в заголовке EXPIRED - то это говорит о том что кеш для данного запроса или страницы устарел, то-есть выделенное время которое описано в директиве fastcgi_cache_valid в моем случае 10 секунд - вышло.
Статус BYPASS - можем наблюдать когда запрос/страница не кешируется. Правила того что не будет попадать в кеш описаны в блоке #Задаем условия, при которых ответ не будет браться из кэша. В моем случае (любая CMS) и все страницы /admin в админ панели не будут кешироваться. Это важно, так как здесь контент постоянно изменяется.
Статус MISS означает что страница не кешируется.
[root@a48zomro ~]# curl -I https://site.com/
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 29 May 2022 11:13:13 GMT
....
....
X-FastCGI-Cache: MISS
[root@a48zomro ~]# curl -I https://site.com/
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 29 May 2022 11:13:23 GMT
....
....
X-FastCGI-Cache: HIT
[root@a48zomro ~]# curl -I https://site.com/admin/
HTTP/1.1 302 Found
Server: nginx
Date: Sun, 29 May 2022 11:13:32 GMT
....
....
X-FastCGI-Cache: BYPASS
[root@a48zomro ~]# curl -I https://site.com/
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 29 May 2022 11:13:39 GMT
....
....
X-FastCGI-Cache: EXPIRED
При данной настройке, наш сайт будет кешироваться и ответ до первого байта может достигать до 2 мс
До оптимизации:
После оптимизации: