Hash 如何使用CDN和负载平衡器进行文件版本控制?

Hash 如何使用CDN和负载平衡器进行文件版本控制?,hash,load-balancing,cdn,azure-load-balancer,multi-instance-deployment,Hash,Load Balancing,Cdn,Azure Load Balancer,Multi Instance Deployment,所以我使用的是一个非常简单的CDN服务。你指向你的网站,如果你通过他们的主机名调用它,他们会在第一次调用后为你缓存它 我将其用于所有静态内容,如JavaScript文件和图像 这一切工程完美-我喜欢它有很少的维护或设置成本 当推出新版本的JavaScript文件时,问题就出现了。如果文件发生更改,新的JavaScript文件将自动获得新的哈希值 但由于在多个实例上展开不是同时发生的,因此会出现问题。我尝试在这个图中对其进行建模: 简言之: 请求使用新版本命中服务器 请求具有新版本哈希的Js文

所以我使用的是一个非常简单的CDN服务。你指向你的网站,如果你通过他们的主机名调用它,他们会在第一次调用后为你缓存它

我将其用于所有静态内容,如JavaScript文件和图像

这一切工程完美-我喜欢它有很少的维护或设置成本

当推出新版本的JavaScript文件时,问题就出现了。如果文件发生更改,新的JavaScript文件将自动获得新的哈希值

但由于在多个实例上展开不是同时发生的,因此会出现问题。我尝试在这个图中对其进行建模:

简言之:

  • 请求使用新版本命中服务器
  • 请求具有新版本哈希的Js文件
  • CDN正确检测到文件未缓存
  • CDN从负载平衡器请求具有新哈希的原始文件
  • loadbalancer向随机服务器提供CDN请求—意外地从旧版本的服务器提供服务
  • CDN使用新哈希缓存旧版本
  • 每个人都可以从CDN获得旧版本的服务
我知道有一些方法可以解决这个问题——例如,手动将文件上传到一个单独的存储区,并加入散列,等等。 但这需要额外的代码,并且有更多的“活动部件”,这使得维护更加复杂

我更愿意拥有与正常CDN行为一样无缝的功能。 我想这对于在多个实例上运行的站点来说是一个常见的问题,但是我找不到很多关于这方面的信息

解决这个问题的常用方法是什么

编辑


我认为另一种解决方案是,以某种方式强制CDN转到与原始html文件相同的.js文件实例-但如何执行?

此类问题的问题是缓存控件位于浏览器端,因此您不能从服务器端执行太多操作

我所知道的最常见的方法基本上就是你提到的向文件名或你用来获取它们的URL添加一些哈希的方法

问题是,您不应该手动执行此操作。您应该使用一些web应用程序生成器(如Webpack)来自动化此过程,这将取决于您使用的技术。13年前,我第一次使用GWT看到了这一点,我使用AngularJS或React处理的所有项目都与自动完成所需任务的构建器集成

一旦实现,您的用户将获得最新版本,并且资源将被正确缓存以加速您的站点


如果您还可以在达到CDN上配置的过期日期后自动执行完整的管道以从CDN中删除旧资源,那么您就触目惊心了。

以下是我过去解决方案中的一些想法,尽管您使用的CDN将排除其中一些想法:

  • 从CDN缓存服务中排除.js文件,首先防止缓存它
  • 在CDN中插入一个请求,请求在发布时使特定文件的缓存失效
  • 在构建/部署脚本中,更改.js文件的名称并在HTML中引用新文件
  • 在.js文件名后使用查询参数,这些参数被忽略,但缓存在不同的地址引用下,例如/mysite/myscript.js?build1234

  • 在运行几分钟后,我通过只引用CDN版本最终解决了这个问题

    因此,如果运行时间少于5分钟,则表示:

    /scripts/example.js?v=351

    5分钟后,它指的是CDN版本:

    https://cdn.example.com/scripts/example.js?v=351

    5分钟后,我们非常确定所有实例都在运行新版本,这样我们就不会意外地用新哈希缓存旧版本


    缺点是,在非常繁忙的时候,如果你想重新部署,你就没有CDN的优势,但我还没有看到更好的选择。

    Hi@Jorge-谢谢你的回答!在单实例环境中,一切都可以完美地工作。一切都已经自动化了。它在多实例环境中出错。WebPack无法解决这个问题。我想我写的问题不够清楚。谢谢你抽出时间回答。嗨@DirkBoer。我的意思是,webpack的输出应该是js文件,比如“main.build12345.js”和指向这些文件的“index.html”文件。客户端将点击请求“main.build12345.js”的CDN,它不可能得到名为“main.build12344.js”的文件名。唯一可能缓存错误的是“index.html”。其余的将是所有具有新名称的新文件。这种方法需要每隔一段时间从旧部署中清理CDN。我错过什么了吗?事实上这是个好主意!我已经习惯于把它放到散列中,但是真正改变文件实际上会在这里产生不同。我仍然有一个问题,如果我使用真实的文件名,CDN实际上可能会从尚未获得新版本的服务器请求它-导致脚本文件的404。