Can Larn be configured to try a second server for some resource if it receives 404 from the main server?

This would be the perfect solution for me, as I need to serve some generated content for web browsers. My plan is to generate content on demand and store it next time. I don’t want browsers to call my service (which generates content) every time. I want them to go directly to the "cached" resource, if one is available, and only call the service if it is not. So I put Varinsh in front of server A, which starts the service, and server B, which stores previously created versions of the content. If he receives a request for a resource that he did not receive in the cache, he will try server B. After receiving a 404 response, he will request the same resource from server A.

Is it possible to adjust the varnish in this way using VCL? If there is no such decision that you know about?

PS I do not want to send 302 redirects to the browser, and I do not have control over server B to send such redirects instead of 404

+5
source share
2 answers

It is quite possible in varnish. Make sure that in vcl_fetch (and possibly in vcl_error) you check the return status code (for example, check stats> 400), restart if it fails, and in vcl_recv select a different 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;
   }
}

, , , -. Varnish - -. (serverA) ? , (), !:)

+5

6 , , 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);
   }

}
0

All Articles