清漆 4 从具有不同内容的多个服务器缓存

varnish 4 to cache from multiple servers with different content

使用varnish 4缓存来自多个服务器的同一请求的不同内容。看起来它缓存了来自一个服务器的第一个请求,并为每个后续请求提供相同的内容。

执行 curl 给出具有两个缓存和不同年龄的响应。

粘性行为是否有任何因素,如负载或其他任何因素? 使用带负载的 Jmeter 和 Apache 基准测试,但仍然有相同的行为。

我的vcl_hash好吗?想用 url 和后端服务器 ip 的哈希组合保存对象。

至少在我的例子中,看起来像在缓存对象的 ttl 之后,清漆从第二个服务器缓存并且 returns 相同,直到 ttl 完成。但这不是我们期望的行为吗?

我错过了什么吗?

使用循环法和hash_data。下面是我的 config.vcl

backend s1{
    .host = "190.120.90.1";
}

backend s2{
    .host = "190.120.90.2";
}

sub vcl_init {
    new vms = directors.round_robin();
    vms.add_backend(s1);
    vms.add_backend(s2);
}

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

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return(lookup);
}

首先要考虑的 事情是只有在从中获取 object 之后,您才会拥有后端 ip。所以你不能在你的哈希方法上使用那个 ip 因为 vcl_hash 发生在获取之前。

其次是循环赛。它仅在 Varnish 获取 object 时发生,因此当 object 已经被缓存时它不会发生。

准确回答您的问题,需要知道为什么您的应用程序会针对同一请求提供不同的内容。如果请求始终相同,您如何指示正在请求哪个后端?必须有诸如 cookie、header 或请求的原始 IP 之类的东西来指示哪个必须响应该请求。

知道可以设置特定的后端并在您的 vcl_hash 中使用它。出于示例目的,假设您要根据名为 backend_choice:

的 header 的存在来设置后端
sub vcl_recv {
  if (req.http.backends_choice == "s1") {
    set req.backend_hint = s1;
  # If the header is not "s1" or does not exist
  } else {
    set req.backend_hint = s2;
  }
  ...
}

sub vcl_hash {
  hash_data(req.url);
  if (req.http.host) {
    hash_data(req.http.host);
  } else {
    hash_data(server.ip);
  }
  # We use the selected backend to hash the object
  hash_data(req.backend_hint);
  return(lookup);
}

希望这个答案能满足您的需求。如果我遗漏了什么,请随时发表评论或添加到您的问题中,我很乐意在我的回答中添加一些信息。