Налаштування Varnish для 1С-Bitrix
PHP-процес Bitrix генерує сторінку каталогу за 200–800 мілісекунд. При 100 одночасних користувачів сервер упирається в обмеження CPU та пам'яті. Varnish кешує HTTP-відповідь та відповідає на подальші запити за 1–5 мс без участі PHP. Однак між Varnish та Bitrix є ряд конфліктів, які ломають автентифікацію, кошик та персональний контент.
Архітектура: Varnish перед Nginx
Стандартна схема: клієнт → Varnish (:80/:443) → Nginx (:8080) → PHP-FPM. Nginx при цьому переводиться на порт 8080. Varnish приймає запити, кешує кешовані та відправляє некешовані прямо бекенду.
клієнт → varnish:80 → nginx:8080 → php-fpm:9000
↓ (cache hit)
varnish cache (RAM)
Встановлення на CentOS/RHEL (типово для Bitrix VM):
yum install varnish
systemctl enable varnish
Ключові проблеми інтеграції з Bitrix
Bitrix використовує сесійні печива PHPSESSID та печива автентифікації BITRIX_SM_*. Varnish за замовчуванням не кешує запити з печивами — це правильно, але надто консервативно. Анонімний користувач з пустим кошиком також отримує печиво сесії і не потрапляє в кеш.
Другий конфлікт — HTTPS. Varnish не терміновує SSL. Вам потрібен Nginx або HAProxy перед Varnish для терміновування SSL. Схема ускладнюється: клієнт → Nginx(:443, SSL) → Varnish(:80) → Nginx(:8080) → PHP-FPM.
Конфігурація VCL для Bitrix
vcl 4.1;
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 5s;
.first_byte_timeout = 120s;
}
sub vcl_recv {
# Примусово HTTP/1.1 (Varnish не підтримує HTTP/2 з бекендом)
set req.http.X-Forwarded-For = client.ip;
# Не кешувати адміністративну панель та авторизацію
if (req.url ~ "^/bitrix/" || req.url ~ "^/area51/") {
return (pass);
}
# Не кешувати POST та авторизованих користувачів
if (req.method == "POST" || req.method == "PUT") {
return (pass);
}
# Авторизований користувач — печиво BITRIX_SM_UIDH
if (req.http.Cookie ~ "BITRIX_SM_UIDH") {
return (pass);
}
# Кошик не пустий
if (req.http.Cookie ~ "BX_BASKET_ADD") {
return (pass);
}
# Видалити печива, які не впливають на контент (аналітика, реклама)
set req.http.Cookie = regsuball(req.http.Cookie,
"(^|;\s*)(_ga|_gid|_gat|_fbp|_ym_uid|_ym_d|_ym_isad)[^;]*", "");
# Якщо печив не залишилося — можна кешувати
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
return (hash);
}
sub vcl_backend_response {
# Не кешувати відповіді з Set-Cookie (автентифікація)
if (beresp.http.Set-Cookie ~ "BITRIX_SM_") {
set beresp.uncacheable = true;
return (deliver);
}
# Кешувати статику надовго
if (bereq.url ~ "\.(css|js|png|jpg|webp|gif|woff2|ico)$") {
set beresp.ttl = 30d;
set beresp.grace = 1d;
unset beresp.http.Set-Cookie;
return (deliver);
}
# HTML-сторінки — 5 хвилин з grace 1 годину
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 5m;
set beresp.grace = 1h;
}
return (deliver);
}
sub vcl_deliver {
# Заголовок налагодження — видалити на продакшені
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
Інвалідація кешу з Bitrix
При оновленні товару або публікації новини Varnish продовжує відповідати старою сторінкою до закінчення TTL. Потрібен механізм примусової інвалідації.
У bitrix/php_interface/init.php додайте обробник подій інфоблоку:
AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', 'PurgeVarnishCache');
AddEventHandler('iblock', 'OnAfterIBlockElementAdd', 'PurgeVarnishCache');
function PurgeVarnishCache($arFields) {
$url = 'http://127.0.0.1/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PURGE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Для вибіркової інвалідації за тегом:
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Cache-Tags: catalog']);
curl_exec($ch);
curl_close($ch);
}
У VCL додайте обробку PURGE-запитів від localhost:
sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip != "127.0.0.1") {
return (synth(403, "Not allowed"));
}
return (purge);
}
}
Varnish та Bitrix Composite
Якщо використовується Bitrix Composite (складені сторінки з AJAX-підгрузкою динамічних блоків) — Varnish не повинен кешувати HTML-основу сторінки, інакше Composite ломається. Або вимкніть кешування HTML через Varnish та залишіть Varnish тільки для статики, або налаштуйте Composite на конкретні компоненти без кешування всієї сторінки через Varnish.







