Недавно наткнулся на Varnish, кеширующий HTML сервер. Для веб-сервера со статикой, думаю, вещь обязательная, если нагрузка отличается от одного пользователя в минуту. Для себя надо решить, стоит ли овчинка выделки, поскольку очень призрачная грань, когда перестает справляться нормально настроенный nginx и тянет только varnish, особенно, если достаточно много динамики.
Суть разницы - nginx кеширует на диске, varnish - в памяти и как-то более для этого предназначен. Собственно, ничто не мешает расположить кеш nginx в памяти (на tmpfs), но вопрос оптимизации остается. В общем, я пока задумался, если у кого-то есть опыт - прошу поделиться. Для вордпрессов и прочего - однозначно, для форума, где много динамики - не уверен. В VBulletin есть еще неприятность в виде создания сессий даже для гостей. Т.е. разделить форум на гостевую и сильно кешируемую часть и на "для зарегистрированных" достаточно сложно.
Предлагается фикс (не мое, еще не пробовал) не выдавать куки для тех, у кого кук нет, если это не POST
Код:
./global.php
до строки require_once(CWD . '/includes/init.php');
поставить
if(empty($_COOKIE)) {
define('SKIP_SESSIONCREATE', 1);
if(empty($_POST)) define('NOCOOKIES', 1);
}
после строки require_once(CWD . '/includes/init.php');
поставить
if(defined('NOCOOKIES')) {
$vbulletin->session->vars['sessionurl'] =
$vbulletin->session->vars['sessionurl_q'] =
$vbulletin->session->vars['sessionurl_js'] =
$vbulletin->session->vars['sessionhash'] = '';
}
а вот вариант vlc для воблы (varnish.vcl):
Код:
backend default {
.host = "127.0.0.1";
.port = "8082";
}
acl purge {
"localhost";
}
# We're running Nginx as our SSL termination point in front of
# Varnish. This way, SSL users still get the benefits of Varnish,
# and we don't have to maintain a separate application.
acl nginx_ssl {
"127.0.0.1";
}
# This is for if you're behind another edge load balancer that
# sends the XFF header.
#acl edge_lb {
# "xxx.xxx.xxx.xxx";
#}
sub vcl_recv {
if (client.ip ~ nginx_ssl && req.http.X-Forwarded-Proto) {
set req.http.X-Forwarded-Proto = "HTTPS";
}
if (client.ip ~ nginx_ssl && req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For;
# } else if (client.ip ~ edge_lb && req.http.X-Forwarded-For) {
# set req.http.X-Forwarded-For = req.http.X-Forwarded-For;
} else {
set req.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
}
if (req.backend.healthy) {
set req.grace = 30s;
} else {
set req.grace = 2m;
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed";
}
return (lookup);
}
if (req.url ~ "^/login\.php" ||
req.url ~ "^/register\.php" ||
req.url ~ "^/usercp\.php" ||
req.url ~ "^/private\.php" ||
req.url ~ "^/profile\.php" ||
req.url ~ "^/admincp") {
return (pass);
}
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset req.http.cookie;
return (lookup);
}
# Change bb_ to your cookie prefix
else {
if (req.http.cookie ~ "bb_imloggedin=yes" ||
req.http.cookie ~ "bb_userid" ||
req.url ~ "\?(.*\&)?s=[a-fA-F0-9]{32}(\&|$)" ||
req.http.cookie ~ "bb_password") {
return (pass);
} else {
unset req.http.cookie;
}
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
return (lookup);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
if (resp.http.magicmarker) {
unset resp.http.magicmarker;
set resp.http.age = "0";
}
}
sub vcl_fetch {
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset beresp.http.expires;
set beresp.http.cache-control = "max-age = 6048001";
set beresp.ttl = 1w;
set beresp.http.magicmarker = "1";
set beresp.http.cacheable = "1";
return(deliver);
}
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
return (hash);
}