循环调度器总是将请求导向同一个后端

循环调度器总是将请求导向同一个后端

我已设置一台使用 Varnish 作为负载均衡器的服务器和两台运行 nginx/unicorn/sinatra 的服务器用于演示目的。所有三台服务器均可访问!我的 varnish 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”需要“socket”

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 机器上进行操作,可以看到后端的正确响应。关闭其中一个 Web 服务器时,Varnish 将使用另一个。但这不是应该在每个请求上都发生吗?

编辑 2:好的,我通过 nginx access_log 文件进行了更多调查,我发现 Varnish 不会对每个请求进行新的查找。对于给定的标头,我认为 Varnish 不会缓存内容。这里的错误是什么?

答案1

你没有提到你使用的是哪个版本的 Varnish。如果我没记错的话,Varnish 并不总是尊重Cache-Controlheader。当前的内置的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相应地设置标头。

相关内容