23

我们最近刚刚注意到 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>
4

3 回答 3

7

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

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

执行超时仅指worker进程处理请求所花费的时间;这只是耗时的一个子集。仅当debug 属性设置为 false时才适用;它看起来像你。

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

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

另一种可能性是页面本身具有调试属性集或它自己的超时值。

于 2010-12-20T15:10:34.960 回答
0

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

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

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

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

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

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

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

于 2011-06-20T18:20:25.450 回答
0

两天前,当我遇到同样的问题时,我遇到了这篇文章。我尝试了一切,它在我的本地机器上工作,但在生产服务器上没有工作。今天,我有一个解决方法,可以解决这个问题,并想分享。微软似乎没有对 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只是一个虚假的异步任务。我所有的业务逻辑仍然在主线程上执行,不会改变当前代码的任何行为。

于 2013-04-16T12:08:38.260 回答