.NET Core 6 MVC容器化应用Socket句柄重复使用异常求助
问题:Debian 11容器中.NET Core 6 MVC接口连续调用后Socket异常
在Debian 11容器中运行.NET Core 6 MVC应用时,连续调用同一控制器接口若干次后抛出异常。该接口逻辑包含读取HTTP请求体、执行数据库操作并返回JSON响应。调试日志显示该端点的Socket连接未正常关闭,完整错误堆栈如下:
2024-04-12T17:13:16.217-07:00 [40m[1m[33mwarn[39m[22m[49m: Microsoft.AspNetCore.Server.Kestrel[0] 2024-04-12T17:13:16.217-07:00 Connection processing ended abnormally. 2024-04-12T17:13:16.217-07:00 System.InvalidOperationException: Handle is already used by another Socket. 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncEngine.TryRegisterCore(IntPtr socketHandle, SocketAsyncContext context, Error& error) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncEngine.TryRegisterSocket(IntPtr socketHandle, SocketAsyncContext context, SocketAsyncEngine& engine, Error& error) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncContext.TryRegister(Error& error) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncContext.OperationQueue`1.StartAsyncOperation(SocketAsyncContext context, TOperation operation, Int32 observedSequenceNumber, CancellationToken cancellationToken) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncContext.ReceiveAsync(Memory`1 buffer, SocketFlags flags, Int32& bytesReceived, Action`5 callback, CancellationToken cancellationToken) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.SocketAsyncEventArgs.DoOperationReceive(SafeSocketHandle handle, CancellationToken cancellationToken) 2024-04-12T17:13:16.217-07:00 at System.Net.Sockets.Socket.ReceiveAsync(SocketAsyncEventArgs e, CancellationToken cancellationToken) 2024-04-12T17:13:16.217-07:00 at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketReceiver.WaitForDataAsync(Socket socket) 2024-04-12T17:13:16.217-07:00 at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketConnection.DoReceive() 2024-04-12T17:13:16.217-07:00 at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result) 2024-04-12T17:13:16.217-07:00 at System.IO.Pipelines.Pipe.ReadAsync(CancellationToken token) 2024-04-12T17:13:16.217-07:00 at System.IO.Pipelines.Pipe.DefaultPipeReader.ReadAsync(CancellationToken cancellationToken) 2024-04-12T17:13:16.217-07:00 at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.BeginRead(ValueTask`1& awaitable) 2024-04-12T17:13:16.217-07:00 at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application) 2024-04-12T17:13:16.217-07:00 at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
排查解决步骤
- 确保请求体完全读取:检查接口代码中是否完整消费了HTTP请求体流,比如使用
await Request.Body.ReadToEndAsync()处理未被模型绑定自动读取的剩余流,未完整读取的流会阻碍Socket连接正常回收。 - 验证数据库资源释放:所有数据库操作必须用
using语句包裹DbContext或数据库连接对象,确保每次请求后数据库连接被及时释放,避免资源泄漏间接影响Socket上下文。 - 调整Kestrel Socket配置:在
Program.cs中修改Kestrel的连接限制参数,优化连接回收逻辑:builder.WebHost.ConfigureKestrel(options => { options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2); options.Limits.MaxConcurrentConnections = 100; options.Limits.MaxConcurrentUpgradedConnections = 100; }); - 升级.NET Core 6补丁版本:该异常属于.NET Core 6已知的Socket资源泄漏bug,升级到6.0.25及以上的补丁版本,官方已修复此类问题。
- 优化容器网络与资源限制:
- 检查Debian容器的网络模式,避免bridge网络的端口映射导致Socket回收异常;
- 增大容器的文件描述符限制,执行
ulimit -n 65535或者在容器启动时配置该参数。
- 检查异步代码规范:确保接口中所有异步操作都使用
await关键字,避免同步阻塞导致Socket上下文无法正确释放,引发资源冲突。
内容的提问来源于stack exchange,提问作者Tathagata Nandi
相关产品推荐
相关产品推荐

