asp.net 使用Kestrel的间歇性.NET 6 Web应用程序崩溃

pgky5nke  于 2023-10-21  发布在  .NET
关注(0)|答案(1)|浏览(299)

我有一个.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.

我不能可靠地使它发生,但它总是最终发生,通常在5-20分钟的跑步后。Web应用程序完全停止,这是我们可以从任何日志中获得的最后一条消息。
这看起来像是某种套接字连接错误,但它发生在本地机器上,它发生在附加的VSCode或VS 2022调试器上。
整个堆栈指向Microsoft代码,没有任何部分指向我们应用程序中的代码。
你知道从哪里开始解决这个问题吗?可能是什么引起的?

cdmah0mi

cdmah0mi1#

造成这种情况的原因是,对于任何从.NET Core升级到现代.NET的人来说,
我们发现dotnet.exew3wp.exe正在创建数百个IPv4环回连接。最后他们会跑出来,我们会得到这个崩溃。
早期版本的Kestrel并不在IIS中运行-相反,IIS会运行一个代理并将连接传递给Kestrel(在answer中有更多内容)。这个代理有一个相当严重的错误-取消令牌会导致IIS关闭连接并继续前进,但IIS不会告诉Kestrel,它会继续运行。
每次取消令牌发生时,w3wp.exe都会取消TCP连接,但dotnet.exe会继续做它正在做的任何缓慢的事情。同时,对于我们的用户来说,事情会变得更慢(更多的是一个队列),所以他们会导航离开,取消另一个请求,使队列变得更糟。
但是我们现在在.NET7上,它应该在进程中运行,对吗?
首先,我们在启动时仍然使用WebHost.CreateDefaultBuilder(.NET Core方法)而不是WebApplication.CreateBuilder(.NET6之后的新方法)-旧的Core方法默认为Kestrel运行进程。
所以我们fixed that up和它仍然发生。
我们忽略了web.config在这里也有一个设置:

<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />

这导致Kestrel仍然会在过多的导航取消发生时耗尽进程并崩溃。
最终的修正是:

<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />

一旦我们完成了所有这些,它终于被修复并停止发生。如果你发现自己在这里有同样的问题,调试你的代码,并检查当前的进程名(Process.GetCurrentProcess().ProcessName)-如果它是w3wp.exe很好,你在IIS中运行,但如果你使用IIS,你得到dotnet.exe,而不是这意味着它的回落到进程外模式,(如果你使用取消令牌)你可以看到相同的连接池相关的崩溃。

相关问题