0

我知道关于这个话题有很多问题和答案。但它们中的大多数是用于 Varnish 3 或不使用 round_robin 导演的。

  • 我在 Varnish 中配置了 2 个网络服务器。
  • 一些静态文件可能只在两个网络服务器之一上生成。
  • 在 404 响应中,我希望清漆尝试其他网络服务器。

目前我已经使用以下 VCL 进行了测试:

sub vcl_init {
    new bar = directors.round_robin();
    bar.add_backend(cbweb1);
    bar.add_backend(cbweb2);
}

sub vcl_recv {
    set req.backend_hint = bar.backend();

    unset req.http.Cookie;
}

sub vcl_deliver {
    if(resp.status == 404 && req.restarts < 1)
    {
        return(restart);
    }
}

在我的小测试中,这似乎有效。但我不明白这是如何工作的。

bar.backend() 是否记得哪些服务器已被使用并跳过那些?或者这只是全局循环,是否有可能,如果在处理期间有另一个请求进入,服务器会被调用两次?

更新: 以下 VCL 似乎可以工作:

sub vcl_init {
    new bar = directors.round_robin();
    bar.add_backend(cbweb1);
    bar.add_backend(cbweb2);
}

sub vcl_recv {
    set req.backend_hint = bar.backend();
}

sub vcl_backend_fetch
{
    if (bereq.retries > 0)
    {
        if(bereq.http.X-Backend == "cbweb1")
        {
            set bereq.backend = cbweb2;
        }
        else
        {
             set bereq.backend = cbweb1;
        }
    }
}

sub vcl_backend_response {
    set bereq.http.X-Backend = beresp.backend.name;

    if (beresp.status == 404 && bereq.retries < 1) {
        return(retry);
    }
}
4

1 回答 1

1

我认为它在你的测试中有效,因为循环。它将一个接一个地尝试服务器。

我认为在生产设置中,由于并发请求,这将不起作用。

如果你重试,它将再次通过 vcl_recv 并从主管那里获得一个 backend_hint,无论 req.restarts 值是什么。如果您想要不同的后端,则必须对其进行编码。

一个想法可能是(代码未经测试,您将不得不调整 X 后端比较):

sub vcl_init {
    new bar = directors.round_robin();
    bar.add_backend(cbweb1);
    bar.add_backend(cbweb2);
}

sub vcl_recv {
    if (req.restarts > 0){
      if (req.X-backend == cbweb1 ){
        set req.backend_hint = cbweb2;
      }
      if (req.X-backend == cbweb2 ){
        set req.backend_hint = cbweb1;
      }
    }
    else {
      set req.backend_hint = bar.backend();
    }
    set req.X-backend = req.backend_hint

    unset req.http.Cookie;
}

sub vcl_deliver {
    if(resp.status == 404 && req.restarts < 1)
    {
        return(restart);
    }
}
于 2017-02-28T17:04:58.733 回答