11

我使用 aHttpHandler来实现一个以高性能为目标的轻量级 Web 服务。它需要一个POSTwith content-type 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 发布。

谢谢你,乔伊·巴雷特

4

3 回答 3

6

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

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

要解决此问题,您可以在应用程序前面安装反向 HTTP 代理。反向代理将卸载读取客户端流(并阻止应用程序中昂贵的线程)的责任,并将完整的请求发送到您的服务器。这将减少应用程序的负载,因为您可以节省宝贵的应用程序线程来处理主要工作负载,而不是阻止它们从客户端流中读取。

此外,您可以卸载 HTTPs、负载平衡,甚至在您的反向代理上缓存一些静态内容(取决于您使用哪一个)。

于 2012-10-10T01:14:40.117 回答
2

System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest()

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

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

西蒙

于 2011-05-19T09:12:06.447 回答
0

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

我搜索了参考来源,得到了“ RequestTimeoutManager”:

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

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

解决方案(可能不是检查):由基于异步的阅读器实现,并手动处理超时......

于 2016-02-24T02:52:15.753 回答