繁体   English   中英

在IIS中托管的WCF有很多打开请求,服务速度很慢

[英]WCF hosted in IIS has lots of open requests and the service is slow down

我有一个基于JSON和POST方法的WCF Web服务,它有一个叫做网站的功能。 此函数有一个简单的代码,只使用下面的代码调用另一个Web服务:

        using (var cli = new MyWebClient())
        {                
            Task<string> t = cli.UploadStringTaskAsync(myURI, "POST", request);
            if (t == await Task.WhenAny(t, Task.Delay(400)))
            {
                response = t.Result;
            }
            else
            {
                response = "";
            }
            cli.Dispose();
        }

MyWebClient类实现为:

class MyWebClient : WebClient
        {
            protected override WebRequest GetWebRequest(Uri address)
            {
                WebRequest request = base.GetWebRequest(address);
                if (request is HttpWebRequest)
                {
                    (request as HttpWebRequest).KeepAlive = true;                    
                    (request as HttpWebRequest).ContentType = "application/json";
                }
                return request;
            }
        }

问题是,我可以在IIS中看到大量请求保持打开超过18秒,甚至更多,我的工作进程中有1或2个(正如您在其中一个附件中看到的那样)! 这使得服务变得非常慢。 请注意,此服务每秒大约有2K个请求,并且此服务的应用程序池具有包含12个工作进程的Web园,队列限制为10K。 当(例如)4个工作进程在可预测的时间(大约450毫秒)内工作时,会发生这种情况,并且IIS显示其请求的最大耗用时间约为380。

IIS中仍有大量请求保持打开状态

请注意,我使用了cli.UploadStringTaskAsync ,因此不考虑cli超时。 所以,我必须实现像t == await Task.WhenAny(t, Task.Delay(400))来模拟超时。

你觉得有什么问题?! 是否使用await导致许多上下文切换并且请求排队等待由cpu执行?


编辑:

在这里你可以找到一些有用的建议,但没有人可以帮助解决问题。 我在我的应用程序的Web配置中设置它们但它无法解决我的问题。


更新:

作为附加信息,请注意网卡为1G,并且最多我们有100Mgb / s的带宽使用率。 Intel Xeon E5-1650 V3 3.5 Ghz有6个内核和12个逻辑处理器。 我们有128GB的RAM和480GB的SSD。

我找到了解决问题的解决方案。 关键点是“processModel元素(ASP.NET设置架构)”。 正如我在问题中提到的那样:

当(例如)4个工作进程在可预测的时间(大约450毫秒)内工作时,会发生这种情况,并且IIS显示其请求的最大耗用时间约为380。

因此,我认为平衡工作进程之间的负载可能是个问题。 通过手动配置processModel元素,我已经解决了这个问题。 在研究了很多之后,我发现了关于processModel Element及其属性的这个有价值的链接。

链接还描述了每个项目的所有属性和效果。 如此链接中所述,有两个重要的属性称为“requestLimit”和“requestQueueLimit”:

requestQueueLimit :指定在ASP.NET开始将消息“503 - Server Too Busy”返回到新请求之前队列中允许的请求数。 默认值为5000。

requestLimit :指定在ASP.NET自动启动新工作进程以取代当前进程之前允许的请求数。 默认为无限。

解决方案是在我的情况下通过有理数控制和限制requestLimit ,例如300。 此外,通过乘以工作进程数和requestLimit来限制requestQueueLimit 我已将工作进程数增加到20,并且通过此配置,6000请求可以完全排队,并且每个工作进程最多有300个请求。 通过每个工作进程达到300个请求,ASP.NET自动启动一个新的工作进程来取代当前进程。

因此,工作进程之间的负载更加均衡。 我检查了所有队列,没有超过400时间的请求!

我认为通过使用这些属性( requestLimitrequestQueueLimit工作进程数 ),此解决方案可以用作IIS和工作进程的半负载平衡器算法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM