You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET线程池尚有大量可用线程时任务仍被排队的原因排查

线程池尚有大量可用线程时,为何任务仍会被排入线程池队列?

问题场景说明

我们的实际代码过于庞大无法完整贴出,以下是最简近似代码:

long running loop
{
  create Task 1
  {
    HTTP Post request (async)
    Wait
  } 
  create Task 2
  {
    HTTP Post request (async)
    Wait
  } 
  Wait for Tasks 1 & 2
}

问题在于,这些通常耗时110-120毫秒的HTTP请求,有时会耗时800-1100毫秒。

预先排查结果

  • 已确认服务器端无延迟
  • 已确认网络层无延迟(通过tcpdump + wireshark分析):即使出现此类延迟,请求间的停顿在TCP层面的周转时间也在100毫秒内

运行环境关键信息

  • 运行环境为Linux
  • 仅在K8s或Docker容器中运行服务时出现此问题,移出容器运行则一切正常

排除线程池饥饿的依据

我们添加了日志记录ThreadPool.GetAvailableThreads的返回值,显示可用线程数分别为32k和4k

确认任务被排队的依据

我们使用dotnet-counters工具观测到,问题发生的同一秒内队列大小可达5

补充说明

  • 我们管控着网络,99.999%确定问题不在网络(当然无法100%保证)
  • 进程未被CPU限流
  • 进程在任意时刻的总线程数通常为25-30个
  • 在K8s/Docker中运行时,已尝试容器网络和主机网络,问题均无变化

HttpClient相关细节

  • 使用的是.NET 6版本的System.Net.Http.HttpClient
  • 客户端实例在启动循环前已创建
  • 请求为HTTP而非HTTPS
  • 每个任务的URL固定,服务器以IP形式指定,例如:http://1.2.3.4/targetfortaskX

总体而言,通过tcpdump和wireshark观测到,有两个TCP连接在整个执行过程中保持打开状态,所有请求均通过这两个连接的keep-alive机制发送,因此不存在DNS解析、TCP握手或源端口耗尽导致的延迟。

内容的提问来源于stack exchange,提问作者Jaroslaw Kruza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:35:28