服务器高负载大请求体时随机出现The client has disconnected错误
我们的ASP.NET Core服务器在高流量场景下,仅针对请求体较大的请求会随机抛出以下错误,且尝试过分块读取请求体后问题仍未解决:
Microsoft.AspNetCore.Connections.ConnectionResetException: The client has disconnected
System.Runtime.InteropServices.COMException: The specified network name is no longer available. (0x80070040)--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.IIS.Core.IO.AsyncIOOperation.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.ReadBody()
at System.IO.Pipelines.PipeCompletion.ThrowLatchedException()
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.ReadAsync(CancellationToken token)
at System.IO.Pipelines.Pipe.DefaultPipeReader.ReadAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.ReadAsync(Memory1 memory, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.IIS.Core.HttpRequestStream.ReadAsyncInternal(Memory1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
错误根源分析
错误代码0x80070040对应网络连接中断,结合大请求体+高流量场景,问题根源通常不在请求体读取方式,而是IIS/Kestrel的请求限制、超时配置,或前端/反向代理的连接超时导致请求未传输完成就被断开。
解决方案
1. 调整IIS请求与应用池配置
- 请求筛选设置:打开IIS管理器→目标站点→请求筛选→编辑功能设置,增大
最大允许内容长度(建议设为1GB即1073741824字节),勾选允许未列出的文件扩展名(若请求体为自定义格式)。 - 应用池优化:进入应用池→高级设置,将
队列长度从默认1000调至2000;进程模型→闲置超时设为0,避免高流量时进程被回收。
2. 优化ASP.NET Core全局配置
- 在
appsettings.json中添加Kestrel限制配置:"Kestrel": { "Limits": { "MaxRequestBodySize": 1073741824, "RequestHeadersTimeout": "00:02:00" } } - 在Program.cs中全局设置请求体大小:
// .NET 6+ 示例 var builder = WebApplication.CreateBuilder(args); // 注册服务... var app = builder.Build(); app.UseHttpsRedirection(); // 全局覆盖请求体大小限制 app.Use(async (context, next) => { var maxSizeFeature = context.Features.Get<IHttpMaxRequestBodySizeFeature>(); if (maxSizeFeature != null) { maxSizeFeature.MaxRequestBodySize = 1073741824; } await next(); }); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 检查反向代理/负载均衡超时设置
如果使用Nginx、Apache或CDN等代理服务:
- Nginx:在server块中添加
client_max_body_size 1g;,调整proxy_connect_timeout 120s;和proxy_read_timeout 120s;。 - Apache:设置
LimitRequestBody 1073741824,调整ProxyTimeout 120。 - 确保CDN/负载均衡未设置过短的连接超时,避免大请求传输中途被断开。
4. 全局捕获异常并优雅处理
在全局异常中间件中捕获该类异常,避免日志泛滥并返回友好提示:
app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>(); var ex = exceptionFeature?.Error; if (ex is ConnectionResetException || (ex?.InnerException is COMException comEx && comEx.HResult == -2147024832)) // 对应0x80070040的HResult { context.Response.StatusCode = StatusCodes.Status499ClientClosedRequest; await context.Response.WriteAsync("请求连接中断,请稍后重试"); } else { context.Response.StatusCode = StatusCodes.Status500InternalServerError; await context.Response.WriteAsync("服务器内部错误"); } }); });
5. 调整TCP/IP网络配置
- 打开注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters:- 设置
TcpTimedWaitDelay为30(十进制,缩短TIME_WAIT状态时长)。 - 设置
MaxUserPort为65534(十进制,增大可用端口范围)。
- 设置
- 检查服务器防火墙规则,排除针对大流量长连接的误拦截。
内容的提问来源于stack exchange,提问作者Abhijit Mutyal

