2011-05-04 53 views
11

我使用HttpHandler来实现针对高性能的轻量级Web服务。它需要POST与内容类型application/x-www-form-urlencoded。 Web服务执行许多任务,包括解密,数据库工作,业务逻辑等。在负载测试期间,性能监视器(ANTS和Visual Studio)指向占用大部分时间的单一代码行,实际上是67%。ASP.NET请求表单性能

string value = context.Request.Form[MY_FORM_KEY]; 

在此行的代码,性能监控,调用堆栈的底部说,这电话:

System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest(); 

是罪魁祸首。

任何人都可以帮忙请解释?该应用程序是在.NET 4中,作为出版发行,IIS 7和Windows Server 2008上

谢谢 乔伊J.巴雷特

+4

如果瓶颈是Request.Form索引器,我会大吃一惊。与你所描述的所有工作相比,这应该是微不足道的。 – 2011-05-04 07:46:23

+0

您可能会多次引用context.Request.Form,相反...您可能需要将您的值克隆到本地变量中 – 2011-05-04 07:52:38

+1

请考虑将其作为头而不是Form变量进行发送。我怀疑表单集合有更多的价值,并提出它使呼叫庞大。您也可以在构建解决方案时检查目标CPU。有时更改为x86可消除Sys​​tem.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest()...的瓶颈 – sajoshi 2011-05-04 09:56:15

回答

2

System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest() 

是一个导入的IIS功能(你可能已经猜到了)。由于http.sys是为IIS执行所有http工作的位,因此它是非托管代码,在某些时候,您的应用程序需要与它交谈,尽管不是直接的。

我猜的是当你阅读表单集合时,.net正在从IIS的原始请求中读取它。如果它被证明是瓶颈,我会重构代码以异步读取表单数据,并将所需的值存储在本机数据结构中。发生

西蒙

6

时间延迟,因为IIS试图从客户端读取请求流来获取表单值。此流受客户端连接影响,并且在某些情况下甚至不会返回。我见过Request.Form会阻塞5分钟以上的情况,并且会导致IIS最终抛出ThreadAbortException。

在我们的例子中,我们有一个HttpModule,它必须通过Request.Form值(或者遍历表单值的request [“key”])来读取它,并且它会在服务器上随机地阻塞,并且永远不会返回。我使用这个HttpModule来跟踪服务器端的应用程序性能,这让我意识到,我使用这个模块跟踪的任何东西都将依赖于客户端的连接,这会歪曲我的服务器端执行结果。

要解决此问题,可以在应用程序的前面安装反向HTTP代理。反向代理将卸载阅读客户端流的责任(并阻止应用程序中的昂贵线程)并将完整的请求发送到您的服务器。这将减少应用程序的负载,因为您可以节省宝贵的应用程序线程以处理主要工作负载,而不是阻止它们读取客户端流。此外,您可以卸载HTTPs,负载平衡,甚至在逆向代理上缓存一些静态内容(取决于您使用的是哪一个)。

0

MgdSyncReadRequest方法阻止了内部非托管IIS API。但提出管理ThreadAbortException
这意味着可能会调用另一个托管线程Thread.Abort()

我搜索referencesource,知道了 “RequestTimeoutManager”:

http://referencesource.microsoft.com/#System.Web/RequestTimeoutManager.cs,177

thread.Abort(new HttpApplication.CancelModuleException(true)); 

解决方案(不检查,可能是):基于异步读写器具,和手动处理超时..