人们在部署大型应用程序时如何解决应用程序池回收问题?

Posted

技术标签:

【中文标题】人们在部署大型应用程序时如何解决应用程序池回收问题?【英文标题】:How are people solving app pool recycle issues on deployment with large apps? 【发布时间】:2011-12-30 09:54:54 【问题描述】:

目前,在构建/部署我们的应用程序(58 个项目,大型 asp.net MVC 3 前端)后,加载整个“回收应用程序池”(发布配置)需要大约 15-20 秒。

如果这会改变人们的答案,我们确实有一个网络农场,但问题是:

在维护窗口不可行的大型应用程序中(我们是一个 24/7 非常活跃的网站),人们在做什么来最大程度地减少部署后应用程序池回收的初始“首次打击”?

我们使用了许多工具来分析启动时间,但似乎没有任何方法可以降低启动时间,所​​以我正在寻找人们采用哪些技术来最大限度地减少影响影响用户的大型应用程序部署。

【问题讨论】:

对这个问题的支持让我大吃一惊。这个问题作为“不是一个真正的问题”可以关闭,并且不包含太多好的信息。 ...因为这是一个非常广泛的话题。 这确实是一个广泛的话题,尽管我不认为这会使它作为一个问题无效 - 在 asp.net mvc 站点中的这种大小 is 应用程序有问题池回收,我只是问人们他们是如何解决/缓解这个问题的? 我的评论更多是关于垃圾投票而不是问题,真的。 我的一个老问题有一些答案***.com/questions/5358020/… 【参考方案1】:

默认情况下 - 如果您一次更改 ASP.NET 应用程序中的 15 个文件(甚至通过 FTP),则应用程序池会自动回收。您可以更改文件的数量,但一旦更改了 web.config 和 bin 文件,就需要对其进行回收。因此,在我看来,像您这样的环境的理想解决方案如下:

4 个网络服务器(这是一个任意数字) 每台服务器都有一个负载均衡器查看的 status.aspx - 使用 TeamCity 使这些服务器中的 2 个“离线”(脱离负载均衡器)并等待 20 秒以过滤流量。分布式缓存将有助于解决用户体验问题

使用 TeamCity 部署到这 2 台服务器 - 运行您的自动化测试等,一旦您满意,将它们放回服务器场,让另外 2 台脱机并部署到这些服务器

这都可以脚本化/自动化。唯一的问题是任何不向后兼容的架构更改可能不允许新版本站点与旧版本站点并行运行 20 秒以使负载均衡器重新启动

这是老式的 Canary 发布 - 这里有一些模式 http://continuousdelivery.com/patterns/ 可以帮助考虑。我还建议一本持续交付书的副本——它就像一本持续交付圣经,让我摆脱了一些情况:)

【讨论】:

Paul 的回答很好,我们内部讨论的内容非常多。虽然问题没有解决,但我很想知道您如何运行 SQL 更改。 我们倾向于使我们的架构更改向后兼容 - 因此通过对我们的数据库进行版本控制,我们可以说站点 x(旧版本的站点)查找架构版本 1,而站点 y(新版本的代码)针对架构版本 2。这样我们可以运行新旧版本。如果我们愿意,这允许我们仅向一组用户发布功能 很有趣,但我看不出这在我们的情况下是如何可行的。我想下次我看到你时我会抓住你的。干杯。【参考方案2】:

在最基础上,您可以在完成部署后对应用程序运行 tinyget 脚本,这将“预热”应用程序,但是如果客户在脚本运行之前访问您的站点,他们仍然会面临延迟。你目前有什么,你有什么部署后步骤?

在场环境中,您也可以进行部署,因此将一台服务器从负载平衡中取出,对其进行更新,然后在部署后使其联机,然后将另一台服务器取出,完成部署,然后重新引入场。您的 SQL Server 设置如何 - 集群?

【讨论】:

这一切都是为了新架构——目前大多数是经典的 ASP,所以根本没有成功。所以这真的是“即将到来”,我们只是在寻找最佳实践。我们已经接受了“将 web1 带出农场,部署,预热,带回农场”,然后冲洗并重复农场的其余部分,这可能是唯一优雅的解决方案 - 我假设有这么多大型网站现在使用 asp.net 衍生品,有人可以优雅地解决这个问题(我会尝试看看 SO 做了什么) 我一直在查看 Web Farm Framework 和 Web Deploy 来查看类似的配置,但没有足够的时间来完全处理大量场景。您每天进行/设想多少次部署?如果可以将多个它们组合在一起,还是您需要那么被动? 不幸的是,他们的反应非常活跃——而且在繁忙时间每天至少 1 次,最多?我见过一天有 10 个部署,虽然都很小,所以可能会分成 4-5 个更大的部署 @AndrewWestgarth 金丝雀发布的好处是你有时间运行一个热身脚本,这样也会有所帮助:)【参考方案3】:

copy and paste from my post here

我们在 4 层架构上执行蓝/绿部署策略,该架构在顶层有一个超过 4 台服务器的网站。由于为部署引入的架构很复杂,我们需要一种在不干扰到“实时”站点的任何流量的情况下进行部署的方法。遵循 Fowler 的建议,但方式不完全相同,我们提出了一个解决方案,这意味着我们在每台服务器上都有 2 个站点(一个蓝色和一个绿色,或者在我们的案例中是站点 A 和站点 B)。活动站点具有适当的主机标头,一旦我们部署并测试到非活动站点,我们就会翻转 2 个站点的标头,以便曾经活动的现在是非活动站点,反之亦然.其效果是,可以在工作时间内以最高的信心完成强大的部署。

这当然会使您的配置和部署稍微复杂化,但值得付出努力。我想不用说你想编写部署和主机头交换的脚本。

【讨论】:

【参考方案4】:

首先,除非您运行的是 Google 或更大的系统,否则凌晨 3 点 15 到 20 秒的加载时间对少数用户真的有那么大的影响吗?我想说消除偶尔延迟所付出的努力将远远超过几个用户在 15 到 20 年代带来的不便。

不幸的是,我认为使用 ASP.NET 是必要的坏事。使用预编译的站点(.DLLs 而不是代码隐藏文件)会减少时间,但不一定会消除它。

您可以做的最好的事情是使用状态通知栏之类的东西来警告用户,他们可能会在“基本维护”期间遇到一些“问题”。 但即便如此,我会说,就用户体验而言,当您的网站一次加载需要 20 秒时,最好保持安静并让少数人指责他们的“网速慢”,而不是向所有人宣布它会很慢。

【讨论】:

如果我们可以依赖该维护窗口,那就太好了,我同意,这不是什么大问题。不幸的是,当站点繁忙时,我们有时每天部署 4-5 次:/ 如果一个网站需要 15-20 秒才能加载,我会去其他地方(除非我不能)。对于几乎所有网站来说,这都是不可接受的延迟。 是的 - 有时这里很忙,虽然目前使用我们的经典 asp 站点显然不是问题(仅部署已更改的站点) - 当使用新架构时,我们必须部署我的 DLL恐慌 @AndrewBarber ...但是如果站点因维护而停机,您会坐等它回来吗? 如果加载了 15 秒,我认为它已经停机进行维护,或者只是简单停机,然后去其他地方。【参考方案5】:

你也可以试试这个方法:http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx

【讨论】:

【参考方案6】:

在对您的网站一无所知的情况下,我的第一个想法是您可以将其分解为更小的网站,以便它们单独启动更快。

其次,对于您的网络场,我假设您在其前面有某种负载平衡设备,您可以在部署机器时将它们从池中拉出。在您向站点发送请求以启动它之前,不要将它们放回池中。您应该能够编写这样的脚本,这样您几乎可以单击一个按钮来取出机器,部署到它,并在它备份并满意后发送请求。

【讨论】:

确实如此:网络农场,到目前为止,这似乎是流行的建议 - 赞成谢谢:)【参考方案7】:

你可以考虑使用aspnet_compiler.exe来预编译你的应用程序,因为我认为部署后的延迟是编译阶段造成的,而不是“整个回收应用程序池”。

【讨论】:

我相信我的 asp.net MVC 应用程序编译的,尽管很多应用程序池回收正在将该应用程序带入应用程序池,以便它可以有效/快速服务。花费的一些时间是编译,但在大多数情况下,除了旧式 asp.net 网站(而不是应用程序)之外,我还没有发现 aspnet_compiler 对其他任何东西都有很大帮助

以上是关于人们在部署大型应用程序时如何解决应用程序池回收问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在事件日志中查找应用程序池回收

IIS应用程序池自动回收问题的有效解决办法

在 Azure 网站上禁用池回收

解决IIS7IIS7.5 应用程序池回收假死的方法

解决IIS7IIS7.5 应用程序池回收假死的方法

如何检查上次回收的应用程序池