假设我有两个生产网络服务器(web1
和web2
)和一个静态资产来源服务器(origin1
),并且我想要部署引用新 css/js/images 的新代码。
在更新web1
并重新轮换之后,并且在我退出web2
轮换之前,将有一个短暂的窗口,在此期间负载均衡器将向web1
新代码和web2
旧代码发送请求:
web1
提供请求的 htmlhttp://somecdn/images/foo.jpg?v=newhash
web2
提供请求的 htmlhttp://somecdn/images/foo.jpg?v=oldhash
因此,在这个短暂的窗口中,可能会somecdn
请求foo.jpg?v=oldhash
,但实际上得到的是刚刚部署到的新镜像origin1
。这不太好。
显而易见的解决方案似乎是保留两个版本的资产:
- 对版本进行版本控制,如
/2.1/images/foo.jpg
和/2.2/images/foo.jpg
,这违背了使用文件哈希进行缓存破坏的目的,或者 - 通过将哈希值添加到文件名来保留两个版本,例如,将和都保留
/images/foo.oldhash.jpg
在/images/foo.newhash.jpg
文件系统中,这会留下一堆需要修剪的旧文件。 - 设置 Varnish 以保留旧版本的 css/js/images(感觉不太可靠)。
假设我在部署时无法完全禁用网站,那么有没有更好的策略?
(StackExchange 使用此文件哈希方法进行缓存清除……)
答案1
如果您要在生产中重叠版本,则基本上必须在过渡期间保持两个版本都可用。使用路径组件中的版本实际上是我们所做的,因为对于开发人员来说,这要简单得多。方法 2 需要在构建/部署过程中进行更多的脚本工作 - 这只是又一个需要打破的事情。我们在底层文件系统中使用硬链接来防止来自 /V1/ 和 /V2/ 的相同文件占用太多空间,并且它也使修剪变得非常容易。我们的源可以处理转换期间增加的命中率(无论如何,这发生在低使用率时期)。