【问题标题】:ASP.Net httpruntime executionTimeout not working (and yes debug=false)ASP.Net httpruntime executionTimeout 不起作用(并且是 debug=false)
【发布时间】:2011-05-28 06:18:15
【问题描述】:

我们最近刚刚注意到 executionTimeout 已停止在我们的网站上运行。它肯定在工作〜去年......很难说它什么时候停止。

我们目前正在运行:

  • Windows-2008x64
  • IIS7
  • 32 位二进制文​​件
  • 托管管道模式 = 经典
  • 框架版本 = v2.0

Web.Config 有

<compilation defaultLanguage="vb" debug="false" batch="true">
<httpRuntime executionTimeout="90" />

关于为什么我们看到 Timetaken 一直到 ~20 分钟的任何提示。 DebugType (full vs pdbonly) 的编译选项有什么影响吗?

datetime       timetaken httpmethod Status  Sent    Received<BR>
12/19/10 0:10  901338    POST       302 456 24273<BR>
12/19/10 0:18  1817446   POST       302 0   114236<BR>
12/19/10 0:16  246923    POST       400 0   28512<BR>
12/19/10 0:12  220450    POST       302 0   65227<BR>
12/19/10 0:22  400150    GET        200 180835  416<BR>
12/19/10 0:20  335455    POST       400 0   36135<BR>
12/19/10 0:57  213210    POST       302 0   51558<BR>
12/19/10 0:48  352742    POST       302 438 25802<BR>
12/19/10 0:37  958660    POST       400 0   24558<BR>
12/19/10 0:06  202025    POST       302 0   58349<BR>

【问题讨论】:

  • 是否有可能在您的应用程序中更深层的另一个 web.config 或 标签覆盖它?可能会以编程方式更改它的 HTTP 模块呢?
  • 在黑暗中拍摄:项目中是否还有其他 web.config 文件。子目录中的一个可以覆盖您当前正在查看的那个。
  • 另一个想法:尝试从受影响的页面打印 HttpContext.Current.Server.ScriptTimeout 并查看它是否符合您的预期。
  • 我遇到了完全相同的问题。而且我已经对其进行了调试,以发现,是的,Server.ScriptTimeout 确实与配置中设置的内容相匹配。 httpRuntime 未在任何其他 web.config 文件中配置。请求会一直运行,直到达到站点范围的连接超时。
  • 解决这个问题有什么好运气吗?我有一个类似的问题。我在页面上打印Server.ScriptTimeout,这确实是我在Web.config中设置的值,但是在“神奇”的90秒之后仍然会发生超时。

标签: asp.net httpruntime executiontimeout


【解决方案1】:

执行超时和耗时是两个不同的东西。虽然,差异的大小令人不安。

time-taken 包括请求/响应中的所有网络时间(在某些conditions.下)。网络传输时间很容易超过请求实际花费的时间。不过,通常情况下,我已经习惯了只有几秒钟的差异,而不是几分钟。

执行超时仅指工作进程处理请求所花费的时间;这只是耗时的一个子集。它仅适用于debug attribute is set to false;看起来你有。

当然,假设您列出的第一个请求占用了全部 90 秒的允许超时时间,那么在时间窗口中仍然剩下 13.5 分钟来传输基本上 24k 的数据。这听起来像是一个严重的网络问题。

因此,要么您遇到了严重的传输问题,要么在树中某处正在处理请求的另一个 web.config 文件将调试设置为 true 或将执行超时增加到天文数字。

另一种可能是页面本身设置了调试属性或它自己的超时值。

【讨论】:

  • 根据 Chris 的 cmets 和一些 MS 文章,我看到 [executiontimeout] 只是 CLR/ASP.NET 中的时间。然而(这可能只是语义上的),我在这个周末发现了一个错误,CLR 请求了大约 30 分钟。我们有一个上下文包装器,它伴随着平台上的每个请求。以下是有关threatabortexception 的日志条目中的时间戳。 [信息] 07:53:48 MXLocale 是美国 {USEnglish} [Err] 08:25:00 Exception()-> System.Threading.ThreadAbortException
  • (上述评论的继续)TAE 被抛出在这一行:oRequestFormColl = Request.Form 对 Request.Form 的任何见解大约需要 30 分钟?
  • @cbcolin:我认为访问 Request.Form 需要这么长时间的唯一原因是,如果将相当大的文件上传到页面。但这是抓住了稻草,因为我认为时间会花在更早的过程中。什么数据被发送到这个页面?
【解决方案2】:

我有一个理论,但我不确定如何证明它。我已经完成了类似于cbcolin 的操作,并记录了请求从BeginRequest 事件处理程序中开始的时间。然后当请求超时时(在我们的例子中是 1 小时后),它会记录在数据库中并记录一个时间戳。

所以这里的理论是:ASP.NET 只计算线程实际执行的时间,而不是它休眠的时间。

所以在BeginRequest 之后,线程进入睡眠状态,直到 IIS 接收到整个 POST 正文。然后线程被唤醒以工作,executionTimeout 时钟开始运行。所以在网络传输阶段花费的时间不计入executionTimeout。最终,站点范围的连接超时被命中,IIS 关闭连接,导致 ASP.NET 中出现异常。

BeginRequest 甚至PreRequestHandlerExecute 都被调用之前 POST 正文被传输到Web 服务器。然后在调用请求处理程序之前有很长的间隔。所以看起来 .NET 有 30 分钟的请求,但线程并没有运行那么长时间。

我将开始记录请求处理程序实际开始运行的时间,并查看它是否超过了我设置的限制。

现在,我不知道如何在每个 URL 的基础上控制请求可以在传输阶段停留多长时间。在全局级别上,我们可以在webLimits 中为应用程序设置 minBytesPerSecond。我找不到它的 UI。这应该会在传输阶段启动超慢客户端。

这仍然不能解决实际发送数据的 DoS 攻击的问题。

【讨论】:

    【解决方案3】:

    我在 2 天前遇到同样的问题时遇到了这篇文章。我尝试了一切,它在我的本地机器上工作,但在生产服务器上没有工作。今天,我有一个解决方法,可以解决这个问题,并想分享。微软似乎没有对 IHttpAsyncHandler 应用超时,我利用了这一点。在我的系统上,我只有一个耗时的处理程序,所以这个解决方案对我有用。 我的处理程序代码如下所示:

    public class Handler1 : IHttpAsyncHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }
    
        public void ProcessRequest(HttpContext context)
        { }
    
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            //My business logic is here
    
            AsynchOperation asynch = new AsynchOperation(cb, context, extraData);
            asynch.StartAsyncWork();
            return asynch;
        }
    
        public void EndProcessRequest(IAsyncResult result)
        { }
    }
    

    还有我的助手类:

    class AsynchOperation : IAsyncResult
    {
        private bool _completed;
        private Object _state;
        private AsyncCallback _callback;
        private HttpContext _context;
    
        bool IAsyncResult.IsCompleted { get { return _completed; } }
        WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
        Object IAsyncResult.AsyncState { get { return _state; } }
        bool IAsyncResult.CompletedSynchronously { get { return false; } }
    
        public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
        {
            _callback = callback;
            _context = context;
            _state = state;
            _completed = false;
        }
    
        public void StartAsyncWork()
        {
            _completed = true;
            _callback(this);
        }
    }
    

    在这种方法中,我们实际上并没有异步执行任何操作。 AsynchOperation 只是一个虚假的异步任务。我所有的业务逻辑仍然在主线程上执行,不会改变当前代码的任何行为。

    【讨论】:

      猜你喜欢
      • 2010-10-04
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 2020-12-18
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多