ASP.NET Core 8.0 Web API部署K8s后出现System.NullReferenceException异常
一、异常情况说明
你的应用运行一段时间后(时长随机)会触发两类未处理异常导致终止重启:
HttpClient连接池相关异常
Unhandled exception in Main: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Concurrent.ConcurrentDictionary`2.Enumerator.MoveNext()
at System.Net.Http.HttpConnectionPoolManager.RemoveStalePools()
at System.Net.Http.HttpConnectionPoolManager.<>c.<.ctor>b__11_0(Object s)
at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool)
at System.Threading.TimerQueue.FireNextTimers()
Kestrel连接管理相关异常
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (Object reference not set to an instance of an object.)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.ConnectionManager.RemoveConnection(Int64 id)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportConnectionManager.RemoveConnection(Int64 id)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.KestrelConnection`1.ExecuteAsync()
--- End of inner exception stack trace ---
这些异常均来自.NET或ASP.NET Core内部组件的并发逻辑,并非业务代码直接触发,但可通过配置调整或版本升级修复。
二、解决方案
1. 处理HttpClient连接池异常
- 调整HttpClient连接池配置:显式设置连接池参数,避免默认值的并发隐患。在
Program.cs中配置:
确保所有HttpClient实例通过DI容器获取,避免手动创建长期持有的静态实例。builder.Services.AddHttpClient("MyClient") .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = 100, PooledConnectionIdleTimeout = TimeSpan.FromMinutes(5), KeepAlivePingTimeout = TimeSpan.FromSeconds(30) }); - 升级.NET 8补丁版本:
ConcurrentDictionary枚举时的NullReferenceException是.NET运行时已知并发bug,升级到最新的.NET 8稳定补丁版本(如8.0.x的最新更新)可修复此类问题。
2. 处理Kestrel连接管理异常
- 调整Kestrel连接限制:在
Program.cs中配置Kestrel的连接超时、最大连接数,减少并发冲突:builder.WebHost.ConfigureKestrel(options => { options.Limits.MaxConcurrentConnections = 1000; options.Limits.MaxConcurrentUpgradedConnections = 1000; options.Limits.IdleTimeout = TimeSpan.FromMinutes(2); }); - 切换HTTP协议版本测试:若使用HTTP/2,暂时切换到HTTP/1.1排查是否为协议层并发问题:
builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(5000, o => o.Protocols = HttpProtocols.Http1); }); - 升级ASP.NET Core补丁版本:Kestrel ConnectionManager的NullReferenceException同样可能是框架已知bug,升级补丁版本是优先解决方案。
3. K8s环境优化
- 调整探针配置:延长存活/就绪探针的超时和间隔,避免应用临时波动时被误重启:
livenessProbe: httpGet: path: /healthz port: 5000 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: httpGet: path: /healthz port: 5000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 - 配置合理资源限制:确保Pod有足够CPU和内存,避免资源不足引发的GC异常或组件崩溃:
resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m"
三、验证步骤
- 优先升级.NET 8到最新补丁版本,这是修复框架内部bug最直接的方式。
- 应用上述配置调整后部署到K8s,观察异常是否复现。
- 若问题持续,开启Debug级日志收集更多上下文:
分析日志中异常发生前的警告或错误信息,进一步定位问题。builder.Logging.AddConsole().SetMinimumLevel(LogLevel.Debug);
内容的提问来源于stack exchange,提问作者Rizwan Hanif

