【问题标题】:NewRelic, async http handler and AcquireRequestStateNewRelic、异步 http 处理程序和 AcquireRequestState
【发布时间】:2016-02-01 14:34:40
【问题描述】:

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

  • 应用程序在带有 .NET Framework 4.5.2 的 win 2012 机器上使用 IIS 8
  • 应用程序已像这样通过 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 中的请求的 sn-p:

   **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(&lt;system.web&gt; 部分)中有 &lt;sessionState mode="Off" /&gt;,所以不是这样。

【问题讨论】:

  • IINM,您没有加载模块,但 Session 仍然“启用”(默认) - 回复:&lt;sessionState mode="Off"&gt; in system.web Hth...
  • 我在 web.config 中有 所以不是这样。我将对其进行编辑以添加该信息
  • 这个浏览器是特定的(仅限 IE)还是全部? ...找到这篇文章:forums.iis.net/t/1169137.aspx
  • 你在 web.config 中有这个设置吗?:&lt;modules runAllManagedModulesForAllRequests="true"&gt;
  • @lord.fist 有没有更多的进展,因为我们每天会得到大约 10 个,如新遗物所示。与您类似的负载,但无法弄清楚可能导致这些异常值的原因。

标签: c# asp.net session asynchronous newrelic


【解决方案1】:

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

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

我们放弃了,所以我很想知道你能不能搞定!

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      所以我遇到了同样的问题。我有很多并发的 ajax 请求,所有使用的变量都存储在 ASP.NET ClaimsIdentity 中,这有效地使用了 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
      

      上面的解决方案公开在this blog article

      【讨论】:

        猜你喜欢
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-08
        • 2011-08-09
        • 1970-01-01
        • 2019-08-12
        相关资源
        最近更新 更多