我有一个.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代码,没有任何部分指向我们应用程序中的代码。
你知道从哪里开始解决这个问题吗?可能是什么引起的?
1条答案
按热度按时间cdmah0mi1#
造成这种情况的原因是,对于任何从.NET Core升级到现代.NET的人来说,
我们发现
dotnet.exe
和w3wp.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
在这里也有一个设置:这导致Kestrel仍然会在过多的导航取消发生时耗尽进程并崩溃。
最终的修正是:
一旦我们完成了所有这些,它终于被修复并停止发生。如果你发现自己在这里有同样的问题,调试你的代码,并检查当前的进程名(
Process.GetCurrentProcess().ProcessName
)-如果它是w3wp.exe
很好,你在IIS中运行,但如果你使用IIS,你得到dotnet.exe
,而不是这意味着它的回落到进程外模式,(如果你使用取消令牌)你可以看到相同的连接池相关的崩溃。