我使用HttpHandler
来实现针对高性能的轻量级Web服务。它需要POST
内容类型application/x-www-form-urlencoded
。 Web服务执行许多任务,包括解密,数据库工作,业务逻辑等。在负载测试期间,性能监视器(ANTS和Visual Studio)指向占用大部分时间的单行代码,实际上是67%。
string value = context.Request.Form[MY_FORM_KEY];
在这行代码的调用堆栈的底部,性能监视器,这个调用说:
System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest();
是罪魁祸首。
任何人都可以帮忙解释一下吗?!该应用程序位于.Net 4,在Windows Server 2008上作为发行版IIS 7发布。
谢谢你, Joey J. Barrett
答案 0 :(得分:6)
发生时间延迟是因为IIS尝试从客户端读取请求流以检索表单值。此流受客户端连接的影响,在某些情况下甚至不会返回。我见过Request.Form会阻塞超过5分钟的情况,这会导致IIS最终抛出ThreadAbortException。
在我们的例子中,我们有一个HttpModule必须通过Request.Form值读取(或者请求[“key”],它也会迭代表单值)并且它会在服务器上随机阻塞而永远不会返回。我使用这个HttpModule来跟踪服务器端的应用程序性能,这让我意识到我使用这个模块跟踪的任何东西也将依赖于客户端的连接,这会扭曲我的服务器端执行结果。
要解决此问题,您可以在应用程序前安装反向HTTP代理。反向代理将卸载读取客户端流的责任(并阻止应用程序中的昂贵线程)并向服务器发送完整请求。这将减少应用程序的负载,因为您可以保存宝贵的应用程序线程来处理主要工作负载,而不是阻止它们从客户端流中读取。
此外,您可以卸载HTTP,负载平衡,甚至在反向代理上缓存一些静态内容(取决于您使用的是哪一个)。
答案 1 :(得分:2)
在
System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest()
是一个导入的IIS函数(您可能已经猜到了)。由于http.sys(用于IIS的所有http工作的位)是非托管代码,因此在某些时候您的应用程序需要与它通信,尽管不是直接的。
我猜测的是,当您阅读表单集时,.net正在从IIS的原始请求中读取此内容。如果它被证明是一个瓶颈,我会重构您的代码以异步读取表单数据并将您需要的值存储在本机数据结构中。
西蒙
答案 2 :(得分:0)
MgdSyncReadRequest
方法阻止了内部非托管IIS API。但提出了管理ThreadAbortException
这意味着另一个托管线程可能是Thread.Abort()
。
我搜索了referencesource,得到了它“RequestTimeoutManager
”:
http://referencesource.microsoft.com/#System.Web/RequestTimeoutManager.cs,177
thread.Abort(new HttpApplication.CancelModuleException(true));
解决方案(不检查,可能):通过基于异步的阅读器实现,并手动处理超时......