如何在IIS 7.5上预热ASP.NET MVC应用程序?

18
我们想要对一个托管在IIS 7.5服务器上的ASP.NET MVC应用程序进行预热。曾经提供的预热模块位于网址http://forums.iis.net/t/1176740.aspx,但在某个时间被移除了。
每次IIS或ASP.NET工作进程由于任何原因重新启动时,都应该预热应用程序。在预热期间,IIS应返回一些HTTP状态代码,表示其预热状态或无法为任何客户端提供服务的情况。
创建一个可执行文件,通过Http请求浏览站点中必要的页面是否是个好主意?该可执行文件可以从IProcessHostPreloadClient实现中触发。是否可能配置IIS仅接受来自本地主机的请求,一旦可执行文件完成,它就可以切换到所有客户端——但这种切换不应触发IIS重新启动(显然)?
是否可能使用Visual Studio 2010 - Web性能测试来预热应用程序,而不是创建手动可执行文件?还有其他选择吗?
备注:应用程序使用Forms身份验证并使用会话——因此维护状态cookie和其他cookie非常重要。
更新1-我们的应用程序使用.NET Framework 4.0和Entity Framework(数据库优先)。第一次访问EF查询很慢。预热的原因是为了在任何最终用户访问应用程序之前进行这些第一次访问。我们已经在大多数地方使用编译查询,并为EF实现了预编译视图。模型和应用程序的大小非常大且复杂。预热需要遍历许多页面,以确保编译和非编译的EF查询至少执行一次,然后任何最终用户才能访问该应用程序。

相关:https://dev59.com/rGYr5IYBdhLWcg3w--wI - Gert Arnold
请尝试查看我的解决方案,它不会返回特殊状态码,而是会等待预热响应请求。 - Jason
3个回答

12

微软发布了一个模块,可以实现你所要求的功能。 IIS 7.5应用程序初始化模块通过在第一次请求到达之前加载Web应用程序来提高网站的响应速度。

您可以指定一系列URL,让IIS在接受真实用户请求之前预加载这些URL。我认为您可能无法获得真实用户登录的体验,但是也许您可以设置模拟页面,这些页面不需要登录,以满足您所要求的预热功能?

我认为最引人注目的功能是,此模块还启用了重叠进程回收。 来自IIS 8.0的以下教程详细介绍了如何逐步启用重叠进程回收。

当IIS检测到正在重复使用活动工作进程时,IIS不会将活动流量切换到新的重复使用的工作进程,直到新工作进程在新进程中运行完所有应用程序初始化URL。这确保了客户在应用程序处于运行状态后浏览您的网站时不会看到应用程序初始化页面。

此IIS应用程序初始化模块内置于IIS 8.0中,但可下载并安装到IIS 7.5上


10
您可以查看以下帖子,了解内置于IIS 7.5和ASP.NET 4.0的自动启动功能。 点击这里

感谢您对此表示关注。请查看原始查询中的“UPDATE 1”,以获取更多有关问题的背景信息。使用ScottGu博客中指定的方法可能无法满足我们所有的要求。我们需要让网站上线-但在它被预热之前不可访问。我们需要在允许所有人访问之前先浏览我们的页面。 - Dhwanil Shah
我能否从IProcessHostPreloadClient的实现代码中访问我的网站页面? - Dhwanil Shah
1
@Dhwanil Shah,你所说的“访问我的网站页面”是什么意思?如果是发送HTTP请求到它们,那么不,你不能在IProcessHostPreloadClient实现中执行此操作,因为IIS在启动过程完成之前不允许任何HTTP请求。这就是预热的全部意义。 - Darin Dimitrov
@Dhwanil Shah,在这种情况下,您不能使用自动启动功能。您将需要编写一些机器人脚本来浏览您的网站。当然,为了使其正常工作,您的网站必须在线上。或者,如果您有可能将其离线供普通用户使用,仍然允许一些内部用户访问它,您可以编写这些脚本以从内部网络或其他地方访问该网站。一旦您使用机器人爬取了所有页面,您就可以将该网站上线。我认为您的问题更适合于http://serverfault.com,因为它与编程不完全相关。 - Darin Dimitrov
我已经在serverfault.com上发布了一个查询 - http://serverfault.com/questions/310479/how-to-configure-iis-7-5-without-restart-call-a-batch-file-on-every-asp-net-res - Dhwanil Shah
显示剩余2条评论

6
任何生成托管资源的服务器请求的应用程序都可以用于预热IIS进程。您需要多少个请求取决于哪些部分需要预热。通常,预热用于:
- 启动工作进程。为此,您只需要请求一个资源即可为整个应用程序预热进程。 - 执行任何静态初始化、数据库启动或预缓存。您在Global.asax文件中执行的任何操作都将在第一次请求时发生,因此如果您可以在那时进行所有初始化,那么您仍然只需要进行一次页面请求。 - 强制预编译ASP.NET页面。为了实现这一点,您需要访问每个页面。幸运的是,这通常不会花费太多时间,所以您可能不需要担心它。如果您确实有单独加载缓慢的页面,则可以单独预热它们。
这里的“预热”过程并没有什么神奇的地方。您只需要强制IIS提供相关的URL即可。您提到的所有方法都可以做到这一点:使用压力测试工具查询URL、编写自定义实用程序来发布HTTP请求,甚至只需编写像'wget'或PowerShell脚本等工具来下载URL即可。
至于限制对本地主机的访问权限,据我所知,在IIS中,更改该权限的唯一方法需要重新启动IIS。您始终可以将预请求钩子构建到应用程序中并在那里维护状态,并使您的预热过程查询某个特定的URL以切换该状态为“打开”。但我不确定您会实现什么目标。如果某些用户在您的预热完成之前尝试查询您的站点,那么所有发生的事情都是您的站点需要很长时间才能响应,然后他们最终会得到所请求的页面。如果您在预热期间将其锁定,则他们将获得一个浏览器网络错误,声称该站点已离线,这(对我来说)听起来更糟糕。

3
在部署网站之前(在构建过程中),您可以预编译页面,这样做的额外好处是发现在 C#/VB.NET 编译期间未被检测到的错误。 - Jakub Konecki
@Michael - 感谢您对此事感兴趣。请查看“更新1”以获取有关查询的更多上下文信息。 - Dhwanil Shah
@Jakub - 我们正在使用ASP.NET预编译。 - Dhwanil Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接