Say I have two production webservers (web1 and web2) and a static asset origin server (origin1), and I want to deploy new code that references new css/js/images.
After updating web1 and putting it back on rotation, and right before I take web2 out of rotation, there'll be a brief window when the load balancer will send requests to both web1 with new code and web2 with old code:
web1serves html that requestshttp://somecdn/images/foo.jpg?v=newhashweb2serves html that requestshttp://somecdn/images/foo.jpg?v=oldhash
So in this brief window, there's a chance that somecdn might request for foo.jpg?v=oldhash, but actually gets served the new image that just got deployed to origin1. That's not good.
The obvious solution seems to be keeping both versions of the assets available:
- Version the releases like
/2.1/images/foo.jpgand/2.2/images/foo.jpg, which defeats the purpose of cache-busting using the file hash, or - Keep both versions by adding the hash to the file name, eg. keep both
/images/foo.oldhash.jpgand/images/foo.newhash.jpgin the file system, which would leave a bunch of old files that needs pruning. - Setup Varnish to keep older versions of css/js/images around (feels iffy).
Is there a better strategy, assuming that I can't disable the site completely while deploying?
(StackExchange uses this file hash approach for cache-busting…)