Service stall pages in case backends are sick

Vassilis Aretakis vassilis at onlab.xyz
Sun Sep 17 18:36:56 UTC 2017


I have a setup which was working on Varnish 3.0 but not with 4.1

The stale pages where servered in case the backends where sick. But I 
cannot make this work with varnish 4.
Can you help me to make it serve the cached pages in case backends are gone?
also session-cookies can be removed/ignored

My config is:


vcl 4.0;
import directors;
import std;

backend b1 {
   .host =
   .port = "80";
   .first_byte_timeout = 180s;
   .between_bytes_timeout = 120s;
   .probe = {
       .url = "/healthy_check/d.php";
       .interval = 10s;
       .timeout = 2 s;
       .window = 7;
       .threshold = 1;
   }
}


backend b2 {
   .host =
   .port = "80";
   .first_byte_timeout = 180s;
   .between_bytes_timeout = 120s;
   .probe = {
       .url = "/healthy_check/d.php";
       .interval = 10s;
       .timeout = 2 s;
       .window = 7;
       .threshold = 1;
   }
}


sub vcl_init {
   new vdir = directors.round_robin();
   vdir.add_backend(b1);
   vdir.add_backend(b2);
}

sub vcl_recv {

   set req.backend_hint = vdir.backend();

   #Ignore adminpanel
   if (req.url == "^/adminpanel/.*" ||
       req.url == "^/adminApplication/.*" ||
       req.url ~ "^/adminApplication/" ||
       req.url ~ "^/adminpanel/" ||
       req.url ~ "^/newsfeed.php" ||
       req.url ~ "^/comment") {
     return (pass);   # unset req.http.Cookie;
   }

   if (req.method != "GET" &&
       req.method != "HEAD" &&
       req.method != "PUT" &&
       req.method != "POST" &&
       req.method != "TRACE" &&
       req.method != "OPTIONS" &&
       req.method != "DELETE") {
     /* Non-RFC2616 or CONNECT which is weird. */
     return (pipe);
   }
   if (req.method != "GET" && req.method != "HEAD") {
       /* We only deal with GET and HEAD by default */
       return (pass);
   }
   #set req.http.grace = "none";

   return (hash);
  }

sub vcl_pipe {

   return (pipe);
}

sub vcl_pass {
   return (fetch);
}

sub vcl_hit {
   if (obj.ttl >= 0s) {
     # normal hit
     return (deliver);
   }
   # We have no fresh fish. Lets look at the stale ones.
   if (std.healthy(req.backend_hint)) {
     # Backend is healthy. Limit age to 10s.
     if (obj.ttl + 10s > 0s) {
       set req.http.grace = "normal(limited)";
       return (deliver);
     } else {
       # No candidate for grace. Fetch a fresh object.
       return(fetch);
     }
   } else {
     # backend is sick - use full grace
     if (obj.ttl + obj.grace > 0s) {
       set req.http.grace = "full";
       return (deliver);
     } else {
       # no graced object.
       return (fetch);
     }
   }
}

sub vcl_miss {
   return (fetch);
}

sub vcl_backend_fetch {
   set bereq.backend = vdir.backend();
}

sub vcl_backend_response {
   # Happens after we have read the response headers from the backend.
   #
   # Here you clean the response headers, removing silly Set-Cookie headers
   # and other mistakes your backend does.
   unset beresp.http.set-cookie;  set beresp.grace = 1h;
   if (beresp.status > 500) {
    return (retry);
   }
   if (bereq.url == "^/") {
     set beresp.ttl = 60s;
   }

   #jpeg caching (forced)
   if (bereq.url ~ "\.(png|gif|PNG|JPG|JPEG|jpg|jpeg|swf|css|js)$" ||
       bereq.url ~ "\.(png|gif|PNG|JPG|JPEG|jpg|jpeg)&width.*" ||
       bereq.url ~ "\.(png|gif|PNG|JPG|JPEG|jpg|jpeg)?.*") {
     set beresp.http.cache-control = "max-age = 2592000";
   }
   return (deliver);
}

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

sub vcl_deliver {
   set resp.http.grace = req.http.grace;
}


More information about the varnish-misc mailing list