Я пытаюсь сбалансировать нагрузку стороннего веб-приложения с помощью Varnish, и для этого стороннего приложения требуется `` настоящее '' имя сервера (похоже, оно подключается к этому серверу по имени в фоновом режиме (а localhost не работает) :() для передачи в строке запроса. Мне также нужна отработка отказа, а это значит, что я хотел бы использовать директоры, чтобы моя конфигурация была простой и масштабируемой.
Вот простой пример того, что я лайк делать:
sub vcl_pass {
set bereq.http.X-Varnish-Backend = bereq.backend.name
}
Однако backend.name доступен в beresp только после того, как мы уже сделали запрос. Похоже, что Varnish не решает, какой бэкэнд использовать, пока после vcl_pass завершается, и нет другого хука до того, как запрос будет отправлен на бэкэнд.
Это верно? Если да, то есть ли другое решение (кроме исправления на веб-сервере, которое я не контролирую)? Без циклов, даже если я реализую замену клиентского директора в VCL, он не сможет масштабироваться дальше пары серверов.
Прежде всего, вы должны разработать стратегию, позволяющую различать используемые приложения. Вы можете использовать разные имена хостов (все они указывают на ваш прокси-сервер Varnish) или вы можете использовать разные URL-адреса, чтобы решить, какой запрос должен обрабатываться какой серверной системой. Если у вас есть стратегия, настройте Varnish:
Пример A) Различные имена хостов
Подготовьте все необходимые бэкенды. Это может быть один сервер или несколько серверов с использованием директора:
backend example1 {
.host = "...";
.port = "...";
...
}
Установите правильный сервер для входящих запросов (в Varnish: req). Я установил дополнительное значение req.http.backend, чтобы использовать его на более позднем этапе. Здесь вы можете заменить или отменить любой HTTP-заголовок клиентского запроса:
sub vcl_recv {
...
if (req.http.host == "example1.mysite.com") {
set req.backend = example1;
set req.http.backend = "example1";
set req.http.host = "application1.internal.mysite.com";
unset req.http.Cache-Control;
...
}
...
}
Внесите некоторые изменения в возвращенный ответ серверной части (в Varnish: beresp). Если у вас есть другое имя хоста для приложения, вы можете изменить перенаправления. Обычно я удаляю некоторые X-заголовки или заменяю кеширующие заголовки back-end здесь:
sub vcl_fetch {
...
if (req.http.backend == "example1") {
...
unset beresp.http.X-Powered-By;
...
if ((beresp.status == 301 || beresp.status == 302) && beresp.http.Location ~ "^http://application1\.internal\.mysite\.com") {
set beresp.http.Location = regsub(beresp.http.Location, "^http://[^/]+", "http://example1.mysite.com");
}
}
...
}
Пример Б) разные URL
В Varnish разница заключается в методе vcl_recv. Позаботьтесь о том, чтобы ваше приложение могло работать с путем "/ example1". Возможны и другие решения, но я бы не рекомендовал это:
sub vcl_recv {
...
if (req.http.host == "www.mysite.com") {
if (req.url ~ "(?i)^/example1/") {
set req.backend = example1;
set req.http.backend = "example1";
set req.http.host = "application1.internal.mysite.com";
unset req.http.Cache-Control;
...
}
...
}
...
}
Вы можете реализовать A или B или объединить A и B. (Более или менее) Все возможно с Varnish.