serving from cache even if the backend is down

Events happening in the community are now at Drupal community events on www.drupal.org.
Greg Coit's picture

If apache or mysql goes down, or you accidentally upload bad code to your drupal site, or you put your site into maintenance mode, apache gives varnish a 5xx. Varnish knows better than to cache this page, but it will serve it if the object grace has expired. Fortunately, varnish has the ability to reset the grace and serve the "good" page from cache until apache returns a non-5xx on that page.

In your /etc/varnish/default.vcl:

add to sub vcl_recv (this is already set in Mercury):

set req.grace = 30s;

add to vcl_fetch:

if ( obj.status == 500) {
    set obj.grace = 60s;
    restart;
  }

This tells varnish to check the source object at most every 1 minutes to see of the status has changed. If apache still returns a 5xx (or doesn't respond), then the grace is reset and the user if given the cached page.

Note that this only works for anonymous users - authenticated users are usually excluded from seeing cached pages.

We're looking to add this to mercury (and letting people update their server if they wish by using the /usr/local/bin/update_mercury.sh script), but need to figure out how to do so without squashing changes that people have already made to their default.vcl

Greg

Comments

james_agnew's picture

Was thinking about how one might be able to use Varnish as a low tech sort of queue manager / waiting room for busy sites. If non-cacheabled pages take more than x seconds to come back from Apache/PHP, then 'hold' the user in Varnish until such time as respectable Apache response times are coming from the back end.

This might be as simple as getting Varnish to show the user a generic cached pages that refreshes every 5 seconds with the URL that the user was trying to reach (e.g. /cart). As soon as Varnish sees that Apache is now responding, then the desired page is pulled from Apache.

I like the idea of using Varnish to handle these high traffic spike situations where some access to dynamic content is required, rather than making matters even worse by getting Apache to process these requests.

Thanks, James

Greg Coit's picture

James,

I think the solution you're looking for is to enable backend polling (using req.backend.healthy - see http://varnish-cache.org/wiki/BackendPolling).

There are some nice varnish examples here: http://varnish-cache.org/wiki/VCLExamples. Note that beresp.grace is only available in dev versions of varnish at the moment, the code I provide above simulates that functionality.

Hope this helps,

Greg

--
Greg Coit
Systems Administrator
http://www.chapterthree.com

Elegant

gchaix's picture

Great solution, Greg!

One question - does the restart directive you added to vcl_fetch respect the "max_restarts" setting?

-Greg (the other one)

re: Elegant

Greg Coit's picture

Greg,

Thanks and yes, the documentation says this does respect the max_restarts variable.

Greg (the other, other one)

--
Greg Coit
Systems Administrator
http://www.chapterthree.com

max restarts * grace = coverage lifetime

joshk's picture

It should also be possible to have the VCL bump up the grace a heck of a lot more. If you have a max_restarts value of 10, this config would give you 10 minutes of max coverage. Some folks might want to make the grace longer depending on their particular balance of freshness vs error-page risk.

Grace and restart on obj.status == 200

effe's picture

It seems to be impossible (varnish 2.0.6) to do a cache response when the lookup sends a status 200.

i tried the following workflow:

  • GET /bla.js

    vcl_recv => lookup
    vcl_fetch => obj comes back but with a content-length of "0" so:
    if (obj.http.Content-Length == "0") {
    set obj.grace = 60s;
    restart;
    }

  • wanted:
    vcl_recv => grace is used so the already cached (but timed out over
    ttl) object will be send out

  • got 4x:
    vcl_recv => lookup
    vcl_fetch => .. like above
    ...
    => client gets an Guru Meditation

I don't know how to force varnish to use the cached object even its ttl
is 0.

I'm using varnish 2.0.6 and for completion in vcl_recv req.grace is 12h
and vcl_fetch obj.grace is 12h.

High performance

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: