This would be a perfect solution for me as I need to serve some generated content to web browsers. My plan is to generate the content on demand and store it for next time. I don't want the browsers to call my service (which generates the content) every time. I want them to go directly to the "cac开发者_JS百科hed" resource if it's available and only call the service if it's not. So I'd put Varinsh in front of server A which runs the service and server B which stores the previously generated content versions. If it gets a request for a resource it hasn't got cached it'll try server B. Upon getting a 404 response it'll request the same resource from server A.
Can Varnish be configured in such a way with VCL? If not is there a solution like that you know about?
P.S. I don't want to send 302 redirects to the browser plus I don't have control over server B to make it send such redirects instead of 404's
This is perfectly possible in Varnish. Make sure that in vcl_fetch (and possibly in vcl_error) you check the return status code (e.g. check for status > 400), do a restart if it failed, and in vcl_recv select the other backend if req.restarts > 0. For example:
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;
}
}
But this being said, it sounds like you're reinventing the concept of a cache server. And Varnish is great cache server. Why not have one back-end server (serverA) and have Varnish cache your generated entities? You can setup complex rules and you'll get expiration (of the cache), purge management and performance for free! :)
In this example, varnish try find in 6 servers, if not found, show the last msg.
# 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);
}
}
精彩评论