奇怪的Asp.Net线程池大小调整行为

奇怪的Asp.Net线程池大小调整行为,asp.net,performance,iis,threadpool,Asp.net,Performance,Iis,Threadpool,我正在对IIS 7.5上托管的.Net 4.0 MVC应用程序进行负载测试(默认配置,尤其是processModel autoconfig=true),并观察到.Net如何管理线程的奇怪行为。 提到“当达到最小值时,线程池可以创建额外的线程或等待某些任务完成”。 线程被阻塞的持续时间似乎在创建新线程还是等待任务完成方面起着作用。不一定会产生最佳吞吐量。 问题:是否有任何方法控制该行为,以便根据需要生成线程并最小化请求队列 观察: 我在一个测试控制器操作上运行了两个测试,除了线程之外,它并没有做太

我正在对IIS 7.5上托管的.Net 4.0 MVC应用程序进行负载测试(默认配置,尤其是processModel autoconfig=true),并观察到.Net如何管理线程的奇怪行为。 提到“当达到最小值时,线程池可以创建额外的线程或等待某些任务完成”。 线程被阻塞的持续时间似乎在创建新线程还是等待任务完成方面起着作用。不一定会产生最佳吞吐量。

问题:是否有任何方法控制该行为,以便根据需要生成线程并最小化请求队列

观察: 我在一个测试控制器操作上运行了两个测试,除了线程之外,它并没有做太多的工作

  • 50个请求/秒,页面休眠1秒
  • 5个请求/秒,页面休眠10秒
对于这两种情况,.Net最好使用50个线程来跟上传入的流量。我观察到的是,在第一种情况下,它并没有这样做,而是同时执行大约20多个请求,让传入的请求排队。在第二种情况下,线程似乎是根据需要添加的

两个测试都产生了100秒的流量。下面是相应的perfmon屏幕截图。 在这两种情况下,都会突出显示Requests Queued计数器(注意0.01缩放)

50/秒测试

对于大多数测试,22个请求是并发处理的(绿松石线)。由于每一个都需要大约一秒钟的时间,这意味着大约30个请求/秒的排队时间,直到测试在100秒后停止生成负载,并且队列慢慢地结束。简单地说,并发数会跳到40以上,但不会跳到50,这是跟上手头流量所需的最小值

这几乎就像线程池管理算法确定创建新线程没有意义一样,因为它具有每秒完成约22个任务(即线程可用)的历史记录。完全忽略了一个事实,即它有一个大约2800个请求等待处理的队列

5/秒测试

相反,在5/sec测试中,线程以稳定的速率添加(红线)。服务器最初会落后,请求会排队,但不会超过52个,最终会添加足够的线程,以便在70多个请求同时执行的情况下关闭队列,即使负载仍在生成

当然,50/sec测试中的工作负载更高,因为处理的http请求数是10倍,但一旦线程池中有足够的线程(例如,通过运行5/sec测试),服务器在处理该流量时就没有任何问题。 它似乎无法处理突然爆发的流量,因为它决定不添加更多线程来处理负载(在这种情况下,它宁愿抛出503个错误,也不愿添加更多线程)。我觉得这很难相信,因为每秒50个请求的流量突发肯定是IIS应该能够在16核机器上处理的。是否有一些设置会促使线程池在创建新线程方面稍微出错,而不是等待任务完成?

看起来是: Microsoft建议您仅在Web服务器上只有很短时间(0到10分钟)有负载时调整最小线程数。在这种情况下,线程池没有足够的时间达到处理负载的最佳线程级别

准确地描述了当前的情况


解决方案:略微增加machine.config中的minWorkerThreads,以处理预期的流量突发。(4将在16核机器上为我们提供64个线程)

虽然我无法解释您看到的行为,但这里有一点贡献:线程池算法不使用队列大小作为输入,也不应该使用。它尝试启发式地最大化吞吐量。(它在这里做不到。)@usr:你说“而且它不应该”是什么意思?在我看来,队列大小在决定是否有必要增加更多线程以最大化吞吐量时至关重要。如果吞吐量在x个线程时是最佳的,为什么队列大小加倍会改变最佳吞吐量?你的案子是伪造的,因为你在睡觉。您拥有+inf.最佳吞吐量。真正的系统在某一点上趋于平稳。(别误会:我仍然在说线程池无法检测到这里的最佳线程数。它应该继续添加。)