AspNetCore 应用程序在生产中泄漏线程 - 如何调试?
AspNetCore app is leaking threads in production - how to debug?
我有一个 ASP.NET Core 2 应用程序正在泄漏线程。我如何确定线程永不消亡的原因?
如果我 运行 应用程序在生产环境中运行 10 分钟,IIS 开始吐出 502.3 Bad Gateway 错误。我加载了 Process Explorer 并查看了 app->Properties->Threads,我看到一个不断增加的线程数:
几乎所有线程都卡在以下本机堆栈跟踪中:
- ntoskrnl.exe!KeWaitForMutexObject+0x8d6
- ntoskrnl.exe!KeDelayExecutionThread+0x9a9
- ntoskrnl.exe!KeWaitForMutexObject+0x1cf
- ntoskrnl.exe!_misaligned_access+0x80d
- ntoskrnl.exe!SeAccessCheck+0x280
- ntoskrnl.exe!KeDelayExecutionThread+0xb49
- ntoskrnl.exe!KeWaitForMutexObject+0x1cf
- ntoskrnl.exe!KeWaitForMultipleObjects+0x2ce
- ntoskrnl.exe!ObWaitForMultipleObjects+0x29c
- ntoskrnl.exe!ObWaitForMultipleObjects+0x713
- ntoskrnl.exe!KeSaveStateForHibernate+0x2a33
- ntdll.dll!ZwWaitForMultipleObjects+0xa
- KERNELBASE.dll!GetProcessHeap+0x62 coreclr.dll+0x4d9c8
- coreclr.dll+0x4db61 coreclr.dll!MetaDataGetDispenser+0x55008
- System.Private.CoreLib.dll+0x58834c
除了我的 Web 应用程序正在泄漏线程外,这些本机堆栈跟踪并没有告诉我太多信息。虽然 Process Explorer 可以向我显示完整 .NET Framework 应用程序的 .NET 堆栈跟踪,但它不会向我显示 .NET Core 应用程序的 .NET 堆栈跟踪。
那么,如何调试这样的问题呢?
我无法在我的本地开发环境中重现它。它似乎与高流量或我的生产服务器环境有关。
到目前为止我尝试过的事情:
- 我的应用程序启用了 stdout 日志:没有关于失败的线索。
- 添加了一个 AppDomain.UnhandledException 处理程序,写入标准输出。没有线索。
- 查看了 Windows 事件日志。没有线索。
我 setup Remote Debugging 在我的服务器上,并且能够从我的开发箱连接到处于不健康状态的应用程序。
在 Visual Studio 中连接到此应用程序后,我可以暂停并检查线程。我看到他们正在等待数据库资源。这就提出了另一个问题,但对于这个特定的 Whosebug 问题来说它是题外话。
我会将此标记为已解决。这里的教训是您可以使用 Remote Debugger + Visual Studio Threads window 来阐明线程泄漏问题。
我有一个 ASP.NET Core 2 应用程序正在泄漏线程。我如何确定线程永不消亡的原因?
如果我 运行 应用程序在生产环境中运行 10 分钟,IIS 开始吐出 502.3 Bad Gateway 错误。我加载了 Process Explorer 并查看了 app->Properties->Threads,我看到一个不断增加的线程数:
几乎所有线程都卡在以下本机堆栈跟踪中:
- ntoskrnl.exe!KeWaitForMutexObject+0x8d6
- ntoskrnl.exe!KeDelayExecutionThread+0x9a9
- ntoskrnl.exe!KeWaitForMutexObject+0x1cf
- ntoskrnl.exe!_misaligned_access+0x80d
- ntoskrnl.exe!SeAccessCheck+0x280
- ntoskrnl.exe!KeDelayExecutionThread+0xb49
- ntoskrnl.exe!KeWaitForMutexObject+0x1cf
- ntoskrnl.exe!KeWaitForMultipleObjects+0x2ce
- ntoskrnl.exe!ObWaitForMultipleObjects+0x29c
- ntoskrnl.exe!ObWaitForMultipleObjects+0x713
- ntoskrnl.exe!KeSaveStateForHibernate+0x2a33
- ntdll.dll!ZwWaitForMultipleObjects+0xa
- KERNELBASE.dll!GetProcessHeap+0x62 coreclr.dll+0x4d9c8
- coreclr.dll+0x4db61 coreclr.dll!MetaDataGetDispenser+0x55008
- System.Private.CoreLib.dll+0x58834c
除了我的 Web 应用程序正在泄漏线程外,这些本机堆栈跟踪并没有告诉我太多信息。虽然 Process Explorer 可以向我显示完整 .NET Framework 应用程序的 .NET 堆栈跟踪,但它不会向我显示 .NET Core 应用程序的 .NET 堆栈跟踪。
那么,如何调试这样的问题呢?
我无法在我的本地开发环境中重现它。它似乎与高流量或我的生产服务器环境有关。
到目前为止我尝试过的事情:
- 我的应用程序启用了 stdout 日志:没有关于失败的线索。
- 添加了一个 AppDomain.UnhandledException 处理程序,写入标准输出。没有线索。
- 查看了 Windows 事件日志。没有线索。
我 setup Remote Debugging 在我的服务器上,并且能够从我的开发箱连接到处于不健康状态的应用程序。
在 Visual Studio 中连接到此应用程序后,我可以暂停并检查线程。我看到他们正在等待数据库资源。这就提出了另一个问题,但对于这个特定的 Whosebug 问题来说它是题外话。
我会将此标记为已解决。这里的教训是您可以使用 Remote Debugger + Visual Studio Threads window 来阐明线程泄漏问题。