Balanceamento de carga do verniz com reescrita de solicitação por servidor

2

Estou tentando balancear a carga de um aplicativo da Web de terceiros com o Varnish, e esse aplicativo de terceiros exige o nome do servidor 'real' (parece se conectar a esse servidor pelo nome em segundo plano (e localhost não Não trabalho :() para ser passado na cadeia de consulta.Eu também preciso de failover, o que significa que eu gostaria de usar os diretores para minha configuração pode ser simples e irá escalar.

Aqui está um exemplo básico do que gostaria :

sub vcl_pass {
  set bereq.http.X-Varnish-Backend = bereq.backend.name
}

No entanto, o backend.name só está disponível no beresp depois que já fizemos a solicitação. Parece que o Varnish não decide qual back-end usar até que após vcl_pass seja concluído e não haja outro gancho antes que a solicitação seja enviada para o back-end.

Isso está correto? Em caso afirmativo, existe outra solução (além de corrigi-lo no servidor da Web, que eu não controle)? Sem loops, mesmo que eu implemente um diretor cliente substituto no VCL, ele não vai escalar além de alguns servidores.

    
por Keenan 15.03.2013 / 19:40

1 resposta

0

Primeiro de tudo você tem que fazer uma estratégia para diferenciar entre os aplicativos usados. Você pode usar nomes de host diferentes (todos eles apontam para seu servidor proxy Varnish) ou você pode usar URLs diferentes para decidir qual solicitação deve ser processada por qual sistema de back-end. Se você tem sua estratégia, configure seu verniz:

Exemplo A) Nomes de host diferentes

Prepare todos os backends necessários. Pode ser um servidor único ou vários servidores usando um diretor:

backend example1 {
  .host = "...";
  .port = "...";
  ...
}

Defina o back-end correto para solicitações recebidas (em Varnish: req). Eu defino um valor adicional req.http.backend, para usá-lo em uma etapa posterior. Aqui você pode substituir ou remover qualquer cabeçalho HTTP da solicitação do cliente:

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;
    ...
  }
  ...
}

Faça algumas modificações com a resposta de back-end retornada (em verniz: beresp). Se você tiver um nome de host diferente para um aplicativo, talvez queira alterar os redirecionamentos. Geralmente eu removo alguns cabeçalhos X ou substituo os cabeçalhos de cache do backend aqui:

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");
    }
  }
  ...
}

Exemplo B) URLs diferentes

Dentro do Varnish, a diferença está no método vcl_recv. Tome cuidado para que seu aplicativo seja capaz de trabalhar com o nome do caminho "/ example1". Outras soluções são possíveis, mas eu não recomendaria:

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;
      ...
    }
    ...
  }
  ...
}

Você pode implementar A ou B ou combinar A e B. (Mais ou menos) Tudo é possível com o verniz.

    
por 17.03.2013 / 13:40