我正在加载测试IIS 7.5上托管的.Net 4.0 MVC应用程序(默认配置,特别是processModel autoconfig = true),并观察.Net如何管理线程的奇怪行为。 http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.100).aspx提到“当达到最小值时,线程池可以创建其他线程或等到某些任务完成”。 似乎线程被阻塞的持续时间在它是创建新线程还是等待任务完成中起作用。不一定会产生最佳吞吐量。
问题:有没有办法控制该行为,因此根据需要生成线程并最小化请求排队?
观察: 我在一个测试控制器动作上运行了两个测试,除了Thread.Sleep之外没有做太多的测试。
对于这两种情况,.Net理想情况下使用50个线程来跟上传入的流量。我观察到的是,在第一种情况下,它没有这样做,而是它同时执行大约20个奇数请求,让传入的请求排队。在第二种情况下,线程似乎根据需要添加。
两项测试都会产生100秒的流量。这是相应的perfmon截图。 在这两种情况下,“请求排队”计数器都会突出显示(请注意0.01缩放)
50 /秒测试
对于大多数测试,22个请求是同时处理的(绿松石线)。每个大约花费一秒钟,这意味着几乎30个请求/秒排队,直到测试在100秒后停止生成负载,并且队列慢慢地消失。简单地说,并发跳转的数量刚好超过40但从不到50,这是跟上手头流量所需的最小值。
几乎好像线程池管理算法确定创建新线程没有意义,因为它具有每秒约22个任务完成(即线程变为可用)的历史记录。完全忽略了它有一个等待处理的大约2800个请求的队列这一事实。
5 /秒测试
相反,在5 / sec测试中,线程以稳定的速率(红线)添加。服务器最初落后,并且请求确实排队,但不超过52,并且最终添加了足够的线程以便队列被解决,同时执行70多个请求,即使仍在生成负载。
当然,50 / sec测试中的工作负载更高,因为正在处理http请求的数量的10倍,但是一旦线程池启动了足够的线程,服务器就没有问题处理该流量(例如,运行5 /秒测试)。 它似乎无法处理突然的突发流量,因为它决定不再添加任何线程来处理负载(它宁可抛出503错误而不是在这种情况下添加更多线程,似乎)。我觉得很难相信,因为一个50个请求/秒的流量突发肯定是IIS应该能够在16核机器上处理的东西。是否有一些设置可以在创建新线程时稍微轻推线程池而不是等待任务完成?
答案 0 :(得分:0)
看起来像是known issue: “Microsoft建议您仅在Web服务器上只有短时间(0到10分钟)加载时调整最小线程数。在这些情况下,ThreadPool没有足够的时间达到最佳级别用于处理负载的线程。“
准确描述了当前的情况。
解决方案:稍微增加machine.config中的minWorkerThreads以处理预期的流量突发。 (4将在16核心机器上给我们64个线程)。