Kei*_*ith 6 asp.net kestrel-http-server .net-6.0
我有一个 .NET 6 Web 应用程序,在使用 Kestrel 时间歇性崩溃:
System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketAwaitableEventArgs.<GetResult>g__ThrowSocketException|5_0(SocketError e)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketAwaitableEventArgs.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketConnection.DoReceive()
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketAwaitableEventArgs.<GetResult>g__ThrowSocketException|5_0(SocketError e)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketAwaitableEventArgs.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketConnection.DoReceive()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
Microsoft.AspNetCore.Server.Kestrel: Warning: Connection processing ended abnormally.
Run Code Online (Sandbox Code Playgroud)
我无法可靠地导致它发生,但它最终总是会发生,通常是在跑步 5-20 分钟后。Web 应用程序完全停止运行,这是我们可以从任何日志记录中获取的最后一条消息。
这看起来像是某种套接字连接错误,但它发生在本地计算机上,并且在附加 VSCode 或 VS2022 调试器时发生。
整个堆栈都指向 Microsoft 代码,其中没有任何部分指向我们应用程序中的代码。
知道从哪里开始解决这个问题吗?可能是什么原因造成的?
造成这种情况的原因是 .NET 中埋藏着一把枪,对于从 .NET Core 升级到现代 .NET 的任何人来说
我们发现了这一点dotnet.exe,并w3wp.exe正在创建数百个 IPv4 环回连接。最终他们用完了,我们就会遭遇车祸。
Kestrel 的早期版本不在 IIS 中运行 - 相反,IIS 会运行代理并将连接传递给 Kestrel(更多内容请参阅此答案)。该代理有一个相当严重的错误 - 取消令牌会导致 IIS 关闭连接并继续,但 IIS 不会告诉 Kestrel,它只会继续运行。
每次发生取消令牌时w3wp.exe都会取消环回连接,但dotnet.exe会继续执行其正在处理的任何缓慢的操作。与此同时,对于我们的用户来说,事情会变得更慢(更多的是队列),因此他们会离开,取消另一个请求并使队列变得更糟。
但我们现在在 .NET7 上,它应该在进程中运行,对吗?
首先,我们在启动时仍然使用WebHost.CreateDefaultBuilder(.NET Core 方法)而不是(.NET6 以来的新方法)——旧的 Core 方法默认为 Kestrel 在进程外运行。WebApplication.CreateBuilder
所以我们解决了这个问题,但它仍然发生了。
我们错过了web.config这里也有一个设置:
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
Run Code Online (Sandbox Code Playgroud)
这导致 Kestrel 仍然会在进程外运行,并且每当发生太多导航取消时就会崩溃。
最终的修复是:
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
Run Code Online (Sandbox Code Playgroud)
一旦我们完成了所有这些,它就终于被修复并不再发生了。如果您发现自己遇到同样的问题,请调试您的代码并检查当前的进程名称 ( Process.GetCurrentProcess().ProcessName) - 如果它w3wp.exe很好,则您正在 IIS 中运行,但如果您使用的是 IIS 并且出现dotnet.exe 相反的情况,则意味着它已回退到 out of进程模式(如果您使用取消令牌)您可能会看到与连接池相关的相同崩溃。
| 归档时间: |
|
| 查看次数: |
892 次 |
| 最近记录: |