IIS7上的ASP.NET应用程序 - iisreset后启动非常缓慢

13

我有一个运行在Windows 2008的IIS7下的ASP.NET 3.5网站。

当我重新启动IIS (iisreset) 并访问一个页面时,初始启动速度非常缓慢。

我在Process Explorer中看到以下活动:

  • w3wp.exe进程被创建,但在大约60秒内显示0%的CPU活动
  • 最后,w3wp.exe的CPU占用率会达到50%,持续大约5秒钟,之后页面才会加载。

我在这段时间内没有看到任何其他进程使用CPU。它基本上就是挂起了。

在所有这些时间内发生了什么?如何跟踪找出是什么导致了这些时间的消耗?

7个回答

6

我们曾经遇到过类似的问题,最终发现是Windows在检查签名证书吊销时超时了。请检查您的服务器是否正在尝试调用某个地方(例如crl.microsoft.com)。也许您的代理设置不正确?或者有防火墙阻挡了请求?我们最终确定对服务器有足够的控制权并且不想‘打电话回家’,所以我们简单地禁用了检查。您可以通过在machine.config中添加以下内容来实现.NET 2.0 SP1及更高版本的禁用检查。

<runtime> <generatePublisherEvidence enabled="false"/> </runtime>

我不确定您是否可以将此内容直接放入您的app.config/web.config文件中。

4

对于那些正在寻找解决IIS慢重启问题的人,请尝试清除临时ASP.Net文件目录。它位于%windir%\Microsoft.NET\Framework [both 64][version]\Temporary ASP.NET Files。 您可以删除此文件夹中的任何内容,但不能删除IIS正在使用的文件(系统会提示您)。 在我的情况下,5 GB的临时文件导致我们的网站在部署后8分钟重启! - ka3yc

4

在运行时编译器(Just-In-Time compiler)将IL代码转换为机器本地代码(汇编),而您需要等待所有操作完成。

当将源代码编译为托管代码时,编译器将源代码转换为Microsoft中间语言(MSIL)。这是一组独立于CPU的指令,可以有效地转换为本地代码。 Microsoft Intermediate Language(MSIL)是许多编译器的输出,也是即时(JIT)编译器的输入。公共语言运行库包括一个JIT编译器,用于将MSIL转换为本地代码。

在Microsoft Intermediate Language(MSIL)执行之前,必须由.NET Framework的即时(JIT)编译器将其转换为本地代码。这是与CPU特定的代码,可在与JIT编译器相同的计算机架构上运行。它不会使用时间和内存将可移植可执行文件(PE)文件中的所有MSIL转换为本地代码。它会按需转换MSIL,然后缓存生成的本地代码,以便对任何后续调用都可以访问。

来源


如果是JIT编译,我不应该在进程资源管理器中看到csc.exe吗?在等待60秒期间,我没有看到csc.exe在运行。 - frankadelic
@csc.exe是C#编译器。JIT是.NET的一部分,这就是为什么运行C#的机器需要安装.NET的原因。 - Ty.
无论是CSC还是JIT,您都会看到CPU使用率。 - Sebastian Good

4
这是将ASP.NET页面编译成中间语言并进行JIT编译的过程 - 它仅在第一次加载页面时发生。(请参见http://msdn.microsoft.com/en-us/library/ms366723.aspx)
如果这真的让你烦恼,那么你可以通过预编译网站来停止它发生。
编辑:刚才重新阅读了问题 - 60秒非常长,你会期望在这段时间内看到一些处理器活动。检查系统和应用程序目标中的事件日志是否有错误/消息。还可以尝试在这60秒内创建w3wp进程的崩溃转储 - 通过查看一些调用堆栈,您可能会认识到它正在做什么。
如果每次都需要确切地 60秒,那么很可能它正在等待某个超时 - 60秒是一个漂亮的圆数。确保它与域控制器等有适当的连接...
(如果有一些IIS诊断工具可以更好地完成工作,那么恐怕我不知道,这个问题可能更适合ServerFault,上述是一种更加开发者式的故障排除方法:-p)

正如其他评论中所提到的 - 在这个延迟期间,我没有看到任何csc.exe在运行。 - frankadelic

2
大于60秒听起来很可疑。尝试运行一个test.html页面来查看需要多长时间。这将隔离出IIS7的作用。
然后,暂时重命名您的web.config、global.asax和应用程序文件夹,并尝试一个test.aspx页面(非常简单的页面)。这将隔离出ASP.NET。
如果这两个都很快(即大约10秒),那么问题可能出在您的应用程序上。但是,如果其中任何一个很慢,则不是应用程序的问题,而是服务器本身的问题。

测试HTML页面在iisreset后大约需要2秒钟。 如果IIS正在运行并且我更改了web.config,则加载测试ASPX页面可能需要3秒钟。 - frankadelic
3
听起来IIS和ASP.NET表现不错。问题可能出在应用程序中。如果只有第一次加载慢,那么可能是因为将代码转换为本机代码。你的项目非常庞大吗?我建议您检查项目类型和大小,并考虑将其分解为部分或预编译后再上传到服务器。 - Scott Forsyth

1

这与JIT编译无关。普通的C#编译器将您的代码文件(.aspx.cs)编译为中间语言,并在启动时将其组装成一个程序集,如果该程序集不存在或代码文件已更改。您的网站程序集位于网站的“bin”文件夹中。

实际上,JIT编译发生在此之后,但这非常快速,不会花费几分钟。JIT编译发生在每个.NET应用程序的启动时,这不会超过几秒钟。

如果您将已编译的网站程序集(YourWebsite.dll)部署到bin文件夹中,则可以避免对您的网站进行编译。也可以仅部署aspx文件并留下代码文件(aspx.cs)。


1
实际上,即使使用预编译站点,.aspx、.ascx等文件也会被解析成C#代码,然后进行编译和即时编译(JIT)。因此,在首次启动ASP.NET应用程序时需要进行相当多的活动。 - Kev

0
我刚刚遇到了类似的问题。对我来说,问题出在我启用了NLog的内部日志记录。这导致启动时间增加了约3分钟!
原始配置:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="false" throwConfigExceptions="false"
      internalLogLevel="Debug"
      internalLogFile="C:\Temp\NLog.Internal.txt">

固定配置

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="false" throwConfigExceptions="false">

关于此信息,我是通过使用SysInternals的ProcMon.exe并过滤进程名称“w3wp.exe”来发现的。


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