IIS应用程序池意外崩溃

时间:2017-11-12 21:15:57

标签: asp.net .net iis application-pool ftp-client

我们现在面临一个非常棘手的问题,差不多一个星期了,我们仍然无法解决它。

问题是我们在IIS上有一个应用程序池,它每天都会崩溃和回收几次。

我们监控了事件查看器上发生的事情,但错误不够详细。

来自Windows事件查看器的2个错误(它们之间为2秒)的示例:

错误1:

Event Id : 1000

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/20/ROOT

Process ID: 14300

Exception: System.ObjectDisposedException

Message: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.

StackTrace:    at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.FtpClient.FtpSocketStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.FtpClient.FtpSocketStream.WriteLine(Encoding encoding, String buf)
   at System.Net.FtpClient.FtpClient.Execute(String command)
   at System.Net.FtpClient.FtpClient.Disconnect()
   at System.Net.FtpClient.FtpClient.Dispose()
   at System.Net.FtpClient.FtpClient.Finalize()

错误2:

事件编号:1325

  Faulting application name: w3wp.exe, version: 8.5.9600.16384, time stamp: 0x52157ba0
    Faulting module name: KERNELBASE.dll, version: 6.3.9600.18666, time stamp: 0x58f32841
    Exception code: 0xe0434352
    Fault offset: 0x00015608
    Faulting process id: 0x37dc
    Faulting application start time: 0x01d35b56102b1ddf
    Faulting application path: C:\windows\SysWOW64\inetsrv\w3wp.exe
    Faulting module path: C:\windows\SYSTEM32\KERNELBASE.dll
    Report Id: b9f70358-c76a-11e7-8111-0cc47a0c4e39
    Faulting package full name: 
    Faulting package-relative application ID: 

此时,我们能够找到哪个错误导致应用池崩溃。它涉及从FtpClient库访问已处置的对象。但是我们仍然无法在代码中找到这样的调用。

然后,我们决定安装DebugDiag(https://www.microsoft.com/en-us/download/details.aspx?id=49924)。顺便说一句非常强大的工具。 我们启动了DebugDiag来监控应用程序池崩溃,我们能够生成非常详细的报告(.mhtml格式)。

这是完整的调用堆栈: .NET调用堆栈

[[HelperMethodFrame]] 
System_ni!System.Net.Sockets.NetworkStream.Write(Byte[], Int32, Int32)+673bde 
System.Net.FtpClient.FtpSocketStream.Write(Byte[], Int32, Int32)+33 
System.Net.FtpClient.FtpSocketStream.WriteLine(System.Text.Encoding, System.String)+44 
System.Net.FtpClient.FtpClient.Execute(System.String)+1c6 
System.Net.FtpClient.FtpClient.Disconnect()+57 
System.Net.FtpClient.FtpClient.Dispose()+46 
System.Net.FtpClient.FtpClient.Finalize()+10 
[[DebuggerU2MCatchHandlerFrame]] 
[[ContextTransitionFrame]] 
[[GCFrame]] 
[[DebuggerU2MCatchHandlerFrame]] 

完整调用堆栈

KERNELBASE!RaiseException+48 
clr!RaiseTheExceptionInternalOnly+27c 
clr!IL_Throw+141 
[[HelperMethodFrame]] 
System_ni!System.Net.Sockets.NetworkStream.Write(Byte[], Int32, Int32)+673bde 
System.Net.FtpClient.FtpSocketStream.Write(Byte[], Int32, Int32)+33 
System.Net.FtpClient.FtpSocketStream.Write(Byte[], Int32, Int32)+33 
System.Net.FtpClient.FtpSocketStream.WriteLine(System.Text.Encoding, System.String)+44 
System.Net.FtpClient.FtpSocketStream.WriteLine(System.Text.Encoding, System.String)+44 
System.Net.FtpClient.FtpClient.Execute(System.String)+1c6 
System.Net.FtpClient.FtpClient.Disconnect()+57 
System.Net.FtpClient.FtpClient.Dispose()+46 
System.Net.FtpClient.FtpClient.Finalize()+10 
clr!MethodTable::FastBox+b0 
clr!MethodTable::CallFinalizer+139 
clr!CallFinalizer+a6 
clr!FinalizerThread::FinalizeAllObjects+a6 
clr!FinalizerThread::FinalizeAllObjects_Wrapper+14 
clr!Thread::DoExtraWorkForFinalizer+1b1 
clr!Thread::DoExtraWorkForFinalizer+234 
clr!Thread::DoExtraWorkForFinalizer+5f8 
[[DebuggerU2MCatchHandlerFrame]] 
clr!Thread::DoExtraWorkForFinalizer+137 
clr!Thread::DoADCallBack+30f 
[[ContextTransitionFrame]] 
clr!Thread::DoExtraWorkForFinalizer+19f 
clr!FinalizerThread::DoOneFinalization+129 
[[GCFrame]] 
clr!FinalizerThread::FinalizeAllObjects+a6 
clr!FinalizerThread::FinalizerThreadWorker+ed 
clr!Thread::DoExtraWorkForFinalizer+1b1 
clr!Thread::DoExtraWorkForFinalizer+234 
clr!Thread::DoExtraWorkForFinalizer+5f8 
[[DebuggerU2MCatchHandlerFrame]] 
clr!ManagedThreadBase::FinalizerBase+33 
clr!FinalizerThread::FinalizerThreadStart+d4 
clr!Thread::intermediateThreadProc+55 
kernel32!BaseThreadInitThunk+24 
ntdll!__RtlUserThreadStart+2f 
ntdll!_RtlUserThreadStart+1b 

我们能够找到导致池崩溃的异常,但我们仍然无法找到代码的哪一部分正在进行调用。 在调用堆栈的底部,您可以注意到第一个事件是:ntdll!_RtlUserThreadStart + 1b,我真的不知道..

所以我很乐意帮助解决这两个问题:

  • 如何在我的代码中找到创建错误的内容?
  • 这样的错误如何使我的应用程序池崩溃并被回收?

环境:   - IIS 8.5   - 应用程序池CLR版本4   - Windows Server 2012 R2

1 个答案:

答案 0 :(得分:1)

消息Cannot access a disposed object表示垃圾收集器已经处理了您的对象,然后您尝试使用它。

您是否使用using调用FtpClient,是否正在执行.close()

错误日志实际上并不实用,如果您发布代码会更好。

此外,将代码放在try...catch中,以便您可以捕获错误而不是将其保留为未处理。有时文件传输失败,因此您需要执行以下操作:

try { 
    using(Stream s = ftpClient.OpenRead()) { 
    // perform your transfer 
    } 
} 
catch(Exception) {
 // Typical exceptions here are IOException, SocketException, or a FtpCommandException 
}