5

这对我来说是一个完美的解决方案,因为我需要为 Web 浏览器提供一些生成的内容。我的计划是按需生成内容并将其存储以备下次使用。我不希望浏览器每次都调用我的服务(生成内容)。如果可用,我希望他们直接转到“缓存”资源,如果不可用,则只调用该服务。因此,我将 Varinsh 放在运行服务的服务器 A 和存储先前生成的内容版本的服务器 B 前面。如果它收到对尚未缓存的资源的请求,它将尝试服务器 B。在收到 404 响应后,它将从服务器 A 请求相同的资源。

Varnish可以用VCL这样配置吗?如果没有,是否有您知道的类似解决方案?

PS 我不想将 302 重定向发送到浏览器,而且我无法控制服务器 B 以使其发送此类重定向而不是 404

4

2 回答 2

5

这在 Varnish 中是完全可能的。确保在 vcl_fetch(可能在 vcl_error)中检查返回状态代码(例如检查状态 > 400),如果失败则重新启动,如果 req.restarts > 0,则在 vcl_recv 中选择另一个后端。例如:

backend serverA {
   .host="192.168.0.1";
   .port = "80";
}

backend serverB {
   .host = "192.168.0.2";
   .port = "80";
}

sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverB;
   } else {
       set req.backend = serverA;
   }
}

sub vcl_fetch {
    if (obj.status >= 400 && req.restarts == 0) {
        restart;
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       restart;
   }
}

但是话虽这么说,听起来您正在重新发明缓存服务器的概念。Varnish 是很棒的缓存服务器。为什么不拥有一台后端服务器(serverA)并让 Varnish 缓存您生成的实体?您可以设置复杂的规则,您将免费获得(缓存的)到期、清除管理和性能!:)

于 2010-12-03T14:43:19.200 回答
0

在本例中,varnish 尝试在 6 个服务器中查找,如果未找到,则显示最后一条消息。

# cat /etc/varnish/default.vcl 
backend serverA {
   .host="10.42.4.104";
   .port = "80";
}

backend serverB {
   .host = "10.42.4.102";
   .port = "80";
}

backend serverC {
   .host = "10.42.4.103";
   .port = "80";
}

backend serverD {
   .host = "10.42.4.101";
   .port = "80";
}

backend serverE {
   .host = "10.42.4.105";
   .port = "80";
}

backend serverF {
   .host = "10.42.4.106";
   .port = "80";
}




sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverA;
   } elseif (req.restarts == 1){
       set req.backend = serverB;
   } elseif (req.restarts == 2){
       set req.backend = serverC;
   } elseif (req.restarts == 3){
       set req.backend = serverD;
   } elseif (req.restarts == 4){
       set req.backend = serverE;
   } else {
       set req.backend = serverF;
   }
}


sub vcl_fetch {
    if (beresp.status >= 400 && req.restarts == 0) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 1) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 2) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 3) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 4) {
        return(restart);
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       return(restart);
   }
   if (req.restarts == 1) {
       return(restart);
   }
   if (req.restarts == 2) {
       return(restart);
   }
   if (req.restarts == 3) {
       return(restart);
   }
   if (req.restarts == 4) {
       return(restart);
   }

}
于 2015-01-20T15:39:00.707 回答