ServerXmlHttpRquest
HTTP の実行に関連する作業を定期的に行う仕事がありますPOST
。ジョブは 60 秒ごとに実行されます。
また、通常は問題なく動作します。ただし、50,000 分の 1 の確率 (2 ~ 3 か月ごと) でハングする可能性があります。
IXMLHttpRequest http = new ServerXmlHttpRequest();
http.open("POST", deleteUrl, false, "", "");
http.send(stuffToDelete); <---hang
ハングすると、タスク スケジューラ (実行に 3 分以上かかる場合にジョブを強制終了するオプションが有効になっている) でさえ、タスクを終了できません。リモートの顧客のネットワークに接続し、サーバーにアクセスし、タスク マネージャーを使用してプロセスを強制終了する必要があります。
そして、さらに1〜3か月は有効です。
最終的に、タスク マネージャーを使用してプロセス ダンプを作成するようになりました。
だから私はハングがどこにあるかを分析することができました. 5 回のクラッシュ ダンプ (過去 11 か月ほど) の後、一貫した画像が得られます。
ntdll.dll!_NtWaitForMultipleObjects@20()
KERNELBASE.dll!_WaitForMultipleObjectsEx@20()
user32.dll!MsgWaitForMultipleObjectsEx()
user32.dll!_MsgWaitForMultipleObjects@20()
urlmon.dll!CTransaction::CompleteOperation(int fNested) Line 2496
urlmon.dll!CTransaction::StartEx(IUri * pIUri, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4453 C++
urlmon.dll!CTransaction::Start(const wchar_t * pwzURL, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4515 C++
msxml3.dll!URLMONRequest::send()
msxml3.dll!XMLHttp::send()
Contoso.exe!FrobImporter.TFrobImporter.DeleteFrobs Line 971
Contoso.exe!FrobImporter.TFrobImporter.ImportCore Line 1583
Contoso.exe!FrobImporter.TFrobImporter.RunImport Line 1070
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.HandleFrobImport Line 433
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.CoreExecute Line 71
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.Execute Line 84
Contoso.exe!Contoso.Contoso Line 167
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()
だから私は をしますServerXmlHttpRequest.send
、そしてそれは決して戻りません。それは何日もそこにとどまります(システムが金融取引を逃す原因となり、日曜日の夜になるまで、システムが壊れているという電話がかかります)。
誰かがコードをデバッグする方法を知らない限り、それは役に立ちませんが、ダンプ時に停止したスレッドのレジスタは次のとおりです。
EAX 00000030
EBX 00000000
ECX 00000000
EDX 00000000
ESI 002CAC08
EDI 00000001
EIP 732A08A7
ESP 0018F684
EBP 0018F6C8
EFL 00000000
- Windows Server 2012 R2
- マイクロソフト IIS/8.5
ServerXmlHttpRequest のデフォルトのタイムアウト
を使用serverXmlHttpRequest.setTimeouts(...)
して、タイムアウトの 4 つのクラスを構成できます。
- resolveTimeout : この値は、ホスト名 (「www.microsoft.com」など) を IP アドレスにマッピングするために適用されます。デフォルト値は∞で、タイムアウトなしを意味します。
- connectTimeout : 長整数。この値は、ターゲット サーバーとの通信ソケットの確立に適用されます。デフォルトのタイムアウト値は 60 秒です。
- sendTimeout : この値は、通信ソケット上の要求データ (存在する場合) の個々のパケットをターゲット サーバーに送信する際に適用されます。サーバーに送信される大きなリクエストは、通常、複数のパケットに分割されます。送信タイムアウトは、各パケットを個別に送信する場合に適用されます。デフォルト値は30 秒です。
- receiveTimeout : この値は、ターゲット サーバーからの応答データのパケットの受信に適用されます。大きな応答は複数のパケットに分割されます。受信タイムアウトは、ソケットからのデータの各パケットのフェッチに適用されます。デフォルト値は30 秒です。
KB305053 (接続を開いたままにしておくことを決定したサーバーは、接続が閉じるまで serverXmlHttpRequest を待機させます) は、もっともらしい問題のようです。しかし、デフォルトの 30 秒のタイムアウトで問題は解決します。
考えられる回避策 - 自分自身をジョブに追加する
Windows タスク スケジューラがタスクを終了できません。オプションが do do に有効になっているにもかかわらず。
Windows Job API を使用してセルフプロセスをジョブに追加し、それを使用SetInformationJobObject
してプロセスに時間制限を設定する方法を検討します。
プロセスの実行時間を 3 分に制限するには:
PerProcessUserTimeLimit LimitFlagsがJOB_OBJECT_LIMIT_PROCESS_TIMEを指定する
場合、このメンバーはプロセスごとのユーザー モード実行時間制限 (100 ナノ秒単位) です。それ以外の場合、このメンバーは無視されます。システムは、ジョブに関連付けられた各プロセスが、設定された制限よりも多くのユーザー モード時間を蓄積しているかどうかを定期的に確認します。存在する場合、プロセスは終了します。
ジョブがネストされている場合、有効な制限は、ジョブ チェーン内で最も制限の厳しい制限です。
タスク スケジューラはジョブ オブジェクトを使用してタスクの時間も制限するため、ジョブ オブジェクトがジョブを制限できるとは思えません。
編集: ジョブ オブジェクトは、プロセス時間によってプロセスを制限することはできません。ユーザー時間のみです。また、プロセスがアイドル状態でオブジェクトを待機している場合、ユーザー時間はまったく蓄積されません (3 分もかからないことは確かです)。
ボーナスリーディング
- ServerXMLHTTP GET 要求はどのようにハングしますか? (
GET
、ないPOST
) - KB305053: POST 要求を送信すると、ServerXMLHTTP が応答を停止します (これは、タイムアウトが期限切れになる必要があることを示しています。私の場合はそうではありません)
- MS フォーラム: oHttp.Send - ハングする (
HEAD
, notPOST
) - MS フォーラム: MSXML2.ServerXMLHTTP Send を使用して SOAP WebService をテストするための ASP がハングする
- CC から MS へのサポート フォーラム