【问题标题】:404 issue with static assets, CDN and multi server environment静态资产、CDN 和多服务器环境的 404 问题
【发布时间】:2013-06-10 08:57:20
【问题描述】:

我们的生产环境出现问题,也许其他人遇到了这个问题并有一个聪明的解决方案。

先决条件:

  • 我们在两台前端服务器前使用负载平衡器。
  • 我们使用 CDN 交付静态资产,例如 CSS/JS/图像。
  • 我们使用 SquishIt 通过校验和对 JS/CSS 文件进行指纹识别,以提供缓存清除功能
  • 我们在应用程序启动时在资产路径前添加 CDN 路径。这也是一个 SquishIt 功能 (.WithOutputBaseHref)。示例:/ui/main_465987ecb75.css 将呈现为 //cdn.host.com/ui/main_465987ecb75.css

部署例程:

  1. 从负载平衡器中移除 server1。
  2. 部署到 server1。
  3. 热身。
  4. 在负载平衡器中包含服务器 1。
  5. 从负载平衡器中取出 server2(...并重复步骤 2-4)

这就是失败的地方:

在上述第 4 步和第 5 步之间,我们让两台服务器都在线了很短的时间。在此期间,server1 可能正在引用 main_46eb48ac968.css,而 server2 可能正在引用 main_987eba4687.css。这会在以下场景中造成麻烦...

用例:

  1. 用户访问该站点并最终访问新部署的服务器 1。
  2. 浏览器将从 CDN 请求 main_46eb48ac968.css。
  3. CDN 从负载均衡器请求该文件,因为它不在其缓存中。
  4. 负载均衡器将 CDN 请求发送到 server2。
  5. Server2 返回 404 page not found 错误,因为新文件仅在服务器 1 上。
  6. 网站看起来很垃圾!

一个简单的解决方法当然是在部署期间不使用 CDN 运行,但由于 CDN url 在应用程序启动期间预先添加到路径中,我们必须在生产中重新启动应用程序...:/

想法?

【问题讨论】:

    标签: .net css deployment squishit


    【解决方案1】:

    嗯,所以您的 CDN 使用您的网站作为我的来源?

    您可能想查看this issue。这样做是将哈希作为 folder 写入生成的路径中,然后您可以使用 IIS 重写规则在进入时从 URL 中删除该文件夹。这样做是为了提供一个选项,该选项提供“文件名中的哈希”选项的可靠缓存清除,而不会爆炸文件。您可以使用它来确保 something 得到服务 - 但在这种情况下,它会在您的 CDN 缓存中留下旧版本的文件(因此您需要在完成部署后使所有内容失效)。

    这将在下一个版本 (0.9.3) 中提供

    【讨论】:

      【解决方案2】:

      回答@AlexCuse

      是的,我们的 CDN 使用该站点作为来源。

      实际上是我提出了 hash-as-virtual-folder-solution :) 在我们部署到发现此问题的多前端服务器环境之前,我们一直使用该解决方案。这是在没有 CDN 多个前端服务器的环境中缓存破坏文件的好方法。不幸的是,我们两者都有。

      如果我们使用哈希作为虚拟文件夹的解决方案,在 50% 的情况下,旧文件使用新 URL 提供,两台服务器都在线的时间很短,一台服务器使用旧代码,另一台使用旧代码新代码。我们确实可以在部署后刷新 CDN,但这不会帮助已经下载错误文件的客户端,因为它的最大使用期限为 365 天,并且在客户端按下 ctrl+F5 之前不会更新。而我们无法控制。废话。 ;)

      因此,到目前为止,我们的决定是让用户在一分钟内获得一个没有 CSS/JS 的蹩脚网站会更好(如果他是第一个访问者并且 命中“错误”服务器)而不是缓存错误文件,直到下次部署才会更新。

      我们还对代码进行了一些更改,现在我们可以在服务器处于生产状态时禁用 CDN,而无需通过删除 http 缓存中存储 CDN URL 的键来回收应用程序池。这有点乏味,因为它涉及登录到 CMS、进行更改、保存、发布然后再更改回来,但这是可能的。

      无论如何,谢谢,这是一个很棒的图书馆!

      【讨论】: