如果从主服务器获取404,可以将Varnish配置为针对某些资源尝试第二台服务器吗?

时间:2010-12-01 18:45:55

标签: http varnish varnish-vcl

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

可以使用VCL以这种方式配置Varnish吗?如果没有这样的解决方案,你知道吗?

P.S。我不想将302重定向发送到浏览器加上我无法控制服务器B以使其发送此类重定向而不是404的

2 个答案:

答案 0 :(得分:5)

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

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缓存生成的实体?您可以设置复杂的规则,您将免费获得(缓存),清除管理和性能的到期! :)

答案 1 :(得分: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);
   }

}