Я установил один сервер с Varnish в качестве балансировщика нагрузки и два сервера с nginx / unicorn / sinatra для демонстрационных целей. Доступны все три сервера! Мой vcl файл с лаком:
backend web2 {
.host = "10.169.42.243";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
backend web1 {
.host = "10.47.137.196";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
director demo round-robin {
{ .backend = web1; }
{ .backend = web2; }
}
sub vcl_recv {
set req.backend = demo;
}
Проверка работоспособности также хороша для обоих бэкэндов:
0 Backend_health - web1 Still healthy 4--X-RH 5 3 5 0.004336 0.003621 HTTP/1.1 200 OK
0 Backend_health - web2 Still healthy 4--X-RH 5 3 5 0.003388 0.004753 HTTP/1.1 200 OK
Мое приложение Sinatra просто показывает IP хоста: требуется «rubygems», требуется «sinatra / base», требуется «сокет»
class MyApp < Sinatra::Base
get '/' do
headers \
"Cache-Control" => "no-cache, no-store, must-revalidate",
"Pragma" => "no-cache",
"Expires" => "0"
'Hello, nginx and unicorn! - ' + Socket.gethostname
end
end
Но когда я получаю доступ к адресу балансировщика нагрузки, я всегда показываю один и тот же IP-адрес. Я могу посетить оба бэкэнда вручную и увидеть их уникальные IP-адреса.
Я пропустил что-то очевидное?
Изменить: я также пробовал curl
с машины Varnish и можете видеть правильный ответ от бэкэндов. При выключении одного из веб-серверов Varnish будет использовать другой. Но разве это не должно происходить по каждому запросу?
Edit2: Хорошо, я провел больше исследований с помощью файлов nginx access_log, и я мог видеть, что Varnish не выполняет новый поиск для каждого запроса. Я думал, что с данными заголовками Varnish не кэширует содержимое. Что за ошибка?
Вы не упомянули, какую версию Varnish вы используете. Если мне не изменяет память, Лак не всегда уважал Cache-Control
заголовок. Электрический ток builtin.vcl хотя проверяет заголовок.
Попробуйте добавить в свой default.vcl
и посмотрите, имеет ли это значение:
sub vcl_fetch {
# Varnish determined the object was not cacheable
if (!(beresp.ttl > 0s)) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
return(hit_for_pass);
}
elseif (req.http.Cookie) {
set beresp.http.X-Cacheable = "NO:Got cookie";
return(hit_for_pass);
}
elseif (beresp.http.Cache-Control ~ "private") {
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(hit_for_pass);
}
elseif (beresp.http.Cache-Control ~ "no-cache" || beresp.http.Pragma ~ "no-cache") {
set beresp.http.X-Cacheable = "Refetch forced by user";
return(hit_for_pass);
# You are extending the lifetime of the object artificially
}
elseif (beresp.ttl < 1s) {
set beresp.ttl = 5s;
set beresp.grace = 5s;
set beresp.http.X-Cacheable = "YES:FORCED";
# Varnish determined the object was cacheable
} else {
set beresp.http.X-Cacheable = "YES";
}
}
VCL, приведенный выше, предназначен для Varnish 3.0, и он проверяет различные условия, которые должны препятствовать кэшированию содержимого, возвращает hit_for_pass
для не кэшируемых элементов и устанавливает X-Cacheable
заголовок соответственно.