NewRelic, async http handler and AcquireRequestState

本文关键字:and AcquireRequestState handler http async NewRelic | 更新日期: 2023-09-27 18:32:42

我在分布式 ASP.NET Web 应用程序中遇到一个异步处理程序的问题。首先让我解释一个用例:

  • 应用程序在 win 2012 计算机上使用 IIS 8 与 .NET Framework 4.5.2
  • 应用程序已通过 web.config 禁用会话和身份验证模块,如下所示

         <system.webServer>
           ....
           <modules>
                <remove name="WindowsAuthentication" />
                <remove name="Session" />
                <remove name="FormsAuthentication" />
            </modules>
         </system.webServer>
    
  • 应用程序使用自定义异步 Web 处理程序来为特定请求提供服务

  • 应用程序具有非常大的流量(每个服务器每分钟大约 50k 个请求,异步处理程序每个服务器每分钟大约有 10k 个请求,全部从 NewRelic 跟踪(
  • 应用程序通过多个 W3WP
  • 进程(2 个 W3WP 进程(和多个虚拟服务器(大约 10 个服务器(分发
  • 应用程序具有大量连接

所有正常的(同步请求(都工作正常,但是做更多工作的异步请求(这就是我们使用异步请求的原因(通常很慢,但NewRelic报告说由于"AcquireRequestState"而变慢。现在我已经查看了谷歌和堆栈溢出,此事件与创建会话有关,但我们在 web.config 中禁用了会话。有谁知道"AcquireRequestState"还能做什么?我们是否缺少一些删除会话状态的地方?将其从web.config添加到machine.config没有任何作用...

以下是NewRelic中请求的片段:

   **Slowest components   Count Duration     %   **
     AcquireRequestState    1   12,600 ms   100%  --> WTF?
     ExecuteRequestHandler  1   5.01 ms     0%
     Integrated Pipeline    1   0.334 ms    0%
     UpdateRequestCache     1   0.3 ms      0%
     EndRequest             1   0.168 ms    0%
     AuthenticateRequest    1   0.161 ms    0%
     Total time                 12,600 ms   100%

编辑:我在 web.config(<system.web> 部分(中<sessionState mode="Off" />,所以不是这样。

NewRelic, async http handler and AcquireRequestState

我已经调查过这个问题,因为我们有类似的问题,我找到了这个论坛帖子,有趣的回复是这样的:

不幸的是,这个问题并不像关闭会话状态那么简单。事实上,在描述 AcquireRequestState 的挑战时,关键短语之一是例如,当涉及到何时引发此事件时,会话状态。在深入研究这一点(实际上查看 .NET 源代码(时,我们可以看到在执行 EventHandler 或创建 RequestNotification 对象时调用它。我敢说还有其他方法和/或事件,当调用时,会引发 AcquireRequestState 事件。追踪他们所有人代表着一种斗争。在更规范化的会话状态讨论之外,这似乎没有被谈论很多。 我们看到此事件引发的最常见位置肯定与会话状态管理有关。但是,在这些异常值中,仍然可以提出这些事件。甚至可以直接从应用程序代码调用它。代理要解决的问题在于它可以识别事件,但很少识别来源。当它作为 ASP 管道的一部分引发时,代理收到的唯一通知是这是事务的一个段。默认情况下,源或事件中执行的方法很少检测代理。 我希望我们能为您提供更多见解。.NET 应用程序内部有很多活动部件,其中一些涉及操作系统本身、IIS、.NET 的版本、方法是否异步、应用程序池设置、执行模式、权限等。 虽然我不想在这里打开第二罐蠕虫,但这让人想起缺少 500 个错误的堆栈跟踪的问题。代理在提供和/或可用时提供堆栈跟踪。堆栈跟踪(如果存在(在 ASP 管道中发生的位置非常重要。有时,它会在任何实际的应用程序代码执行之前发生。在这种情况下,错误将报告给应用程序,而应用程序又允许 .NET 代理查看并报告发生了错误,但不提供其他详细信息。代理只是看到它发生了并报告尽可能多的信息。除此之外,代理商根本没有可以提供的进一步细节。

我们放弃了,所以我很想知道你是否想通了!

AcquireRequestState 也被 Profile Module 使用。您是否尝试禁用它?

<modules>
   <remove others unwanted modules... />
   <remove name="Profile" />
</modules>

所以我有同样的问题。我有很多并发的ajax请求,这些请求都使用存储在 ASP.NET ClaimIdentity中的变量,它有效地使用SessionState。这意味着,很多服务器响应时间只是在等待 SessionState 被解锁。

我通过减少锁定轮询间隔解决了它:

var sessionStateModuleType = typeof(SessionStateModule);
var pollingIntervalFieldInfo = sessionStateModuleType.GetField("LOCKED_ITEM_POLLING_INTERVAL", BindingFlags.NonPublic | BindingFlags.Static);
pollingIntervalFieldInfo.SetValue(null, 30); // default 500ms
var pollingDeltaFieldInfo = sessionStateModuleType.GetField("LOCKED_ITEM_POLLING_DELTA", BindingFlags.NonPublic | BindingFlags.Static);
pollingDeltaFieldInfo.SetValue(null, TimeSpan.FromMilliseconds(15.0)); // default 250ms

上述解决方案已在此博客文章中披露