0

我们注意到我们的一个 Web 应用程序有一个相当奇怪的行为。在本地开发人员工作站上调试它时,一切都处理得很好(使用 Cassini 开发网络服务器)。当使用 IIS 6.0 在远程 Web 服务器上发布时,处理运行正常大约 4 或 5 分钟,然后突然停止。

稍后我将解释“突然死亡”的含义,首先我想摘录失败的代码。

// loads data from SAP Webservice and serializes it into database    
LoadXMLDataFromSAP();

// loop each item of a certain structure and parse data
foreach (var xItem in xSapData)
{
    // method determining a status, about 30 LOC, fast execution
    GetStatusCodeForContract(xItem);

    ...

    // methods to parse data blocks, about 400 LOC, slow execution (database etc.)
    TimeconsumingParserMethod1(xItem);
    TimeconsumingParserMethod2(xItem);
}

此代码在调试时运行良好,执行大约需要 13 分钟(没关系,因为它仅在与 SAP 同步所有数据时发生)。在 IIS 6.0 上针对 SAME SAP 数据源运行 SAME 代码时,执行将在 4 或 5 分钟后停止。

首先,程序在调用“TimesumptionParserMethod1()”时抛出 System.NullReferenceException,在下一个循环中,我们在“GetStatusCodeForContract()”中得到 System.NullReferenceException。由于我们在两个调用中使用相同的参数,我认为 NullReferenceException 被抛出是因为成员“xItem”为空。

服务器配置:

8 Core Intel machine
4 GB of RAM
RequestTimeout = 900 (15 minutes)
Memory usage = unlimited

有人知道 IIS 6 或类似生产服务器环境中的这种行为吗?

4

1 回答 1

0

好吧,我终于找到了问题所在。由于我们本地测试服务器上的 EventLog 存在一些问题,我没有注意到一些 IIS 异常。

问题的根源不是任何超时设置,而是 ASP.NET 2.0 的 AppDomain 回收行为。如果您在 Web 请求期间更改了很多文件夹结构,AppDomain 会重新加载,这会导致神秘的 NullReferenceExceptions。

以下文章帮助我找到了问题:http : //weblogs.asp.net/owscott/archive/2006/02/21/ASP.NET-v2.0-2D00-AppDomain-recycles_2C00_-more-common-than-之前的.aspx

链接下方的代码片段是使用的解决方法(它只是禁用了对子文件夹的文件监视,对 web.config 和程序集的更改仍然重新加载 AppDomain 以进行自动部署)。

System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

object o = p.GetValue(null, null);

System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);

object monitor = f.GetValue(o);

System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { });
于 2009-11-30T16:22:50.717 回答