web-dev-qa-db-ja.com

ASP.Net httpruntimeexecutionTimeoutが機能していません(そしてはいdebug = false)

最近、executionTimeoutがWebサイトで機能しなくなったことに気づきました。昨年は間違いなく機能していました...いつ停止したかはわかりません。

現在、以下を実行しています。

  • Windows-2008x64
  • IIS7
  • 32ビットバイナリ
  • マネージドパイプラインモード=クラシック
  • フレームワークバージョン= v2.0

Web.Configには

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

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>
21
cbcolin

実行タイムアウトと所要時間は2つの異なるものです。しかし、不一致の大きさは厄介です。

time-takenには、要求/応答のすべてのネットワーク時間が含まれます(特定の 条件 。)。ネットワーク転送時間は、リクエストが実際にかかる時間を簡単に上回ります。しかし、通常、私は数分ではなく数秒の違いに慣れています。

実行タイムアウトは、ワーカープロセスがリクエストの処理に費やした時間のみを指します。これは、時間のほんの一部です。 デバッグ属性がfalseに設定されている ;の場合にのみ適用されます。あなたが持っているように見えます。

もちろん、リストした最初のリクエストが許可されたタイムアウトの完全な90秒を要したと仮定すると、基本的に24kのデータを転送するために、所要時間ウィンドウに13.5分が残ります。それは深刻なネットワークの問題のように聞こえます。

したがって、重大なトランスポートの問題があるか、ツリーのどこかにリクエストが処理されている別のweb.configファイルがあり、デバッグをtrueに設定するか、実行タイムアウトを天文学的なものに増やします。

もう1つの可能性は、ページ自体にデバッグ属性が設定されているか、ページ自体のタイムアウト値があることです。

7
NotMe

私には理論がありますが、それを証明する方法がわかりません。 cbcolin と同様のことを行い、BeginRequestイベントハンドラー内からリクエストが開始された時刻をログに記録しました。次に、リクエストがタイムアウトすると(この場合は1時間後)、データベースに記録され、タイムスタンプが記録されます。

つまり、理論は次のとおりです。ASP.NETは、スレッドが実際に実行されている時間のみをカウントし、スレッドがスリープしている時間はカウントしません。

したがって、BeginRequestの後、スレッドはPOST本体全体がIISによって受信されるまでスリープ状態になります。その後、スレッドはウェイクアップされて作業を行い、executionTimeoutクロックが実行されます。そのため、ネットワーク送信フェーズで費やされた時間はexecutionTimeoutにカウントされません。最終的に、サイト全体の接続タイムアウトが発生し、IISが接続を閉じて、例外が発生します。 ASP.NETで。

BeginRequestおよびPreRequestHandlerExecuteもすべて呼び出されますbeforePOST本文が転送されますリクエストハンドラが呼び出される前に長いギャップがあります。したがって、.NETが30分間リクエストを受け取ったように見えますが、スレッドはそれほど長く実行されていませんでした。

リクエストハンドラーが実際に実行を開始する時刻のログ記録を開始し、設定した制限を超えていないかどうかを確認します。

リクエストがこのような送信フェーズにとどまる時間をURLごとに制御することについては、私にはわかりません。グローバルレベルでは、アプリケーションの webLimits にminBytesPerSecondを設定できます。私が見つけることができるそのためのUIはありません。これにより、送信フェーズで超低速のクライアントがキックされます。

それでも、実際にデータを送信するDoS攻撃の問題は解決されません。

0

私は2日前に同じ問題を抱えていたときにこの記事に出くわしました。私はすべてを試しました、それは私のローカルマシンで動作しましたが、本番サーバーでは動作しませんでした。今日、私は問題を修正する回避策を持っており、共有したいと思います。 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は単なる偽のasynタスクです。私のビジネスロジックはすべてメインスレッドで実行されており、現在のコードの動作は変更されていません。

0
Khanh TO