ASP.Net httpruntimeexecutionTimeout 不起作用(是的 debug=false)

发布于 2024-10-08 15:08:48 字数 1141 浏览 0 评论 0原文

我们最近注意到我们网站上的executionTimeout 已停止工作。去年它确实在起作用……很难说它何时停止。

我们当前运行于:

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

Web.Config 有

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

任何提示说明为什么我们看到 Timetaken 一直长达约 20 分钟。 DebugType 的编译选项(full 与 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>

We just recently noticed that executionTimeout has stopped working on our website. It was definitely working ~last year ... hard to say when it stopped.

We are currently running on:

  • Windows-2008x64
  • IIS7
  • 32bit binaries
  • Managed Pipeline Mode = classic
  • Framework version = v2.0

Web.Config has

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

Any hints on why we are seeing Timetaken all the way up to ~20 minutes. Would compilation options for DebugType (full vs pdbonly) have any effect?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

允世 2024-10-15 15:08:48

执行超时和执行时间是两个不同的东西。尽管如此,差异的大小仍然令人不安。

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

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

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

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

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

Execution timeout and time-taken time two different things. Although, the size of the discrepancy is troubling.

time-taken includes all of the network time in the request/response (under certain conditions.). The network transfer time easily outstrips the amount of time a request really takes. Though, normally, I'm used to just seconds of difference not minutes.

Execution timeout refers only to the amount of time the worker process spent processing the request; which is just a subset of time-taken. It only applies if the debug attribute is set to false; which it looks like you have.

Of course, assuming the first request you listed took the full 90 seconds of allowed time out, that still leaves 13.5 minutes left in the time-taken window to transfer essentially 24k of data. That sounds like a serious network issue.

So, either you have a serious transport issue or there is another web.config file somewhere in the tree where the requests are being processed that either sets debug to true or increases the execution timeout to something astronomical.

Another possibility is that the page itself has either the debug attribute set or it's own timeout values.

半枫 2024-10-15 15:08:48

内部 HTTP 操作变为异步后,IIS 执行超时在(Core 之前的)ASP.NET 中停止工作。当 HTTP 操作是同步的时,运行时只是观察请求的线程存活了多长时间,然后在时间太长的情况下杀死它,这是有效的,因为一个线程总是与一个请求相关联。但是,一旦框架发展到 HTTP 操作变得异步,超时模型就不再起作用,因为一个线程最终会处理多个请求,因此您不能在这样那样的时间后安全地终止线程。

https://serverfault.com/questions/ 1068281/asp-net-iis-requests-not-timing-out-after-executiontimeout-value/1128469

IIS execution timeouts stopped working in (pre-Core) ASP.NET after the internal HTTP operations became asynchronous. When HTTP operations were synchronous, the runtime just watched to see how long a request's thread lived and then killed it if it took too long, and that worked because one thread was always tied to one request. But once the framework evolved to where the HTTP operations became asynchronous, that timeout model no longer worked because one thread ends up handling multiple requests, so you can't just safely kill a thread after such and such a time.

https://serverfault.com/questions/1068281/asp-net-iis-requests-not-timing-out-after-executiontimeout-value/1128469

墨洒年华 2024-10-15 15:08:48

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

因此,理论是这样的:ASP.NET 只计算线程实际执行的时间,而不计算线程休眠的时间。

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

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

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

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

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

I have a theory but I'm not sure how to prove it. I've done something similar to cbcolin and logged the time when the request starts from within the BeginRequest event handler. Then when the request times out (1 hour later in our case) it is logged in the database and a timestamp recorded.

So here is the theory: ASP.NET only counts time that the thread is actually executing, not time that it is asleep.

So after BeginRequest the thread goes to sleep until the entire POST body is received by IIS. Then the thread is woken up to do work and the executionTimeout clock starts running. So time spent in the network transmission phase is not counted against the executionTimeout. Eventually the site wide Connection Timeout is hit and IIS closes the connection, resulting in an exception in ASP.NET.

BeginRequest and even PreRequestHandlerExecute all get called before the POST body is transferred to the web server. Then there is a long gap before the request handler is called. So it may look like .NET had the request for 30 minutes but the thread wasn't running that long.

I'm going to start logging the time that the request handler actually starts running and see if it ever goes over the limit I set.

Now as to control how long a request can stay in the transmittions phase like this on a per URL basis I have no idea. On a global level we can set minBytesPerSecond in webLimits for the application. There is no UI for it that I can find. This should kick ultra slow clients in the transmission phase.

That still wont solve the problem for DoS attacks that actually send data.

吹梦到西洲 2024-10-15 15:08:48

两天前,当我遇到同样的问题时,我看到了这篇文章。我尝试了一切,它在我的本地计算机上工作,但在生产服务器上不起作用。今天,我有一个解决该问题的解决方法并愿意与大家分享。 Microsoft 似乎没有对 IHttpAsyncHandler 应用超时,我利用了这一点。在我的系统上,我只有 1 个耗时的处理程序,因此这个解决方案适合我。
我的处理程序代码如下所示:

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 只是一个假的异步任务。我的所有业务逻辑仍然在主线程上执行,这不会改变当前代码的任何行为。

I came across this article 2 days ago when I had the same problem. I tried everything, it worked on my local machine but did not work on the production server. Today, I have a workaround that fixes the problem and would like to share. Microsoft seems to not apply timeout to IHttpAsyncHandler and I take advantage of that. On my system, I only have 1 handler that is time-consuming, so this solution works for me.
My handler code looks like this:

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)
    { }
}

And my helper class:

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);
    }
}

In this approach, we actually do not do anything asynchronously. AsynchOperation is just a fake async task. All of my business logic is still executed on the main thread which does not change any behavior of the current code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文