WCF タイムアウト例外の詳細な調査
-
13-09-2019 - |
質問
IIS7 上で実行される WCF サービス (*.svc) と、サービスをクエリするさまざまなクライアントを持つアプリケーションがあります。サーバーは Win 2008 Server を実行しています。クライアントは Windows 2008 Server または Windows 2003 Server を実行しています。次の例外が発生します。これは、実際には多数の潜在的な WCF 問題に関連している可能性があることがわかりました。
System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
タイムアウトを 30 分に増やしましたが、依然としてエラーが発生しました。これは、アップロードまたはダウンロードに 30 分かかるはずのない量のデータがあるため、何か他のことが起こっていることを示しています。
エラーは出たり消えたりします。現時点では、その頻度が増えています。同時に 3 つのクライアントを実行しているか、100 のクライアントを実行しているかは問題ではないようですが、それでも時々発生します。ほとんどの場合、タイムアウトは発生しませんが、それでも 1 時間に数回タイムアウトが発生します。エラーは、呼び出されたメソッドのいずれかによって発生します。これらのメソッドの 1 つはパラメーターを持たず、ビットのデータを返します。もう 1 つは、大量のデータをパラメータとして受け取りますが、非同期に実行されます。エラーは常にクライアントから発生し、スタック トレースでサーバー上のコードを参照することはありません。常に次のように終わります。
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
サーバー上:私は次のバインド設定を試しました(そして現在も使用しています)。
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
影響はないようです。
私は次のスロットリング設定を試しました(そして現在も行っています)。
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentInstances="1500" maxConcurrentSessions="1500"/>
影響はないようです。
現在、WCF サービスには次の設定があります。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
一緒に走った ConcurrencyMode.Multiple
しばらく待ってもエラーは発生しました。
IIS を再起動し、基盤となる SQL Server を再起動し、マシンを再起動してみました。これらすべては影響を与えていないようです。
Windowsファイアウォールを無効にしてみました。影響はないようです。
クライアントには次の設定があります。
maxReceivedMessageSize="2147483647"
<system.net>
<connectionManagement>
<add address="*" maxconnection="16"/>
</connectionManagement>
</system.net>
クライアントが接続を閉じます。
var client = new MyClient();
try
{
return client.GetConfigurationOptions();
}
finally
{
client.Close();
}
より多くの発信接続を許可するようにレジストリ設定を変更しました。
MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
私は最近 SvcTraceViewer.exe を試してみました。クライアント側で例外を 1 つキャッチすることができました。持続時間は 1 分であることがわかります。サーバー側のトレースを見ると、サーバーがこの例外を認識していないことがわかります。私が見ることができる最大持続時間は 10 秒です。
を使用してアクティブなデータベース接続を調べました exec sp_who
サーバー上で。ほんの数個(2~3個)しか持っていません。TCPview を使用して、1 つのクライアントからの TCP 接続を調べました。通常は2~3件ですが、私は5~6件まで見たことがあります。
簡単に言えば、私は困惑しています。見つけられるものはすべて試しましたが、WCF の専門家ならわかるであろう非常に単純な何かが欠けているはずです。私の直感では、サーバーが実際にメッセージを受信する前に、何かが低レベル (TCP) でクライアントをブロックしているか、または何かがサーバー レベルでメッセージをキューに入れて決して処理させていないのではないかと感じています。
確認すべきパフォーマンス カウンターがある場合は、お知らせください。(これらのカウンターの一部は解読が難しいため、どの値が不正であるかを示してください)。また、WCF メッセージ サイズをログに記録するにはどうすればよいですか?最後に、クライアントとサーバーの間に(アプリケーションから独立して)確立できる接続の数をテストできるツールはありますか?
御時間ありがとうございます!
6 月 20 日に追加された追加情報:
私の WCF アプリケーションは次のようなことを行います。
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
WireShark を使用すると、エラーが発生すると 5 回の TCP 再送信が行われ、その後 TCP がリセットされることがわかりました。私の推測では、RST は接続を切断している WCF から来ていると思われます。取得した例外レポートは、ステップ 3 のタイムアウトによるものです。
これは、TCP ストリーム「tcp.stream eq 192」を見て発見しました。次に、フィルターを「tcp.stream eq 192 and http and http.request.method eq POST」に拡張したところ、このストリーム中に 6 つの POST が確認されました。これは奇妙に思えたので、tcp.stream eq 100 などの別のストリームで確認しました。3 回の POST がありましたが、3 回の呼び出しを行っているため、これはもう少し普通のことのように思えます。ただし、WCF 呼び出しのたびに接続を閉じるので、ストリームごとに 1 つの呼び出しが発生すると予想していました (ただし、TCP についてはあまり知りません)。
もう少し調査して、http パケットの負荷をディスクにダンプして、これら 6 つが何をどこで呼び出しているのかを調べました。
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
私の推測では、2 つの同時クライアントが同じ接続を使用しているため、重複が見られたのだと思います。ただし、理解できない問題がまだいくつかあります。
a) パケットが破損しているのはなぜですか?ネットワーク上の偶然のまぐれ - たぶん?ロードは、次のサンプル コードを使用して gzip 圧縮されます。 http://msdn.microsoft.com/en-us/library/ms751458.aspx - 同時に使用すると、コードにバグが発生することがありますか?gzip ライブラリを使用せずにテストする必要があります。
b) 破損した操作がタイムアウトになった後、ステップ 1 とステップ 2 が実行されているのはなぜですか?これらの操作は行われるべきではなかったように私には思えます。私の TCP に対する理解に欠陥があるため、正しいストリームを見ていないのかもしれません。同時に発生する他のストリームもあります。他のストリームを調査する必要があります。ストリーム 190 ~ 194 をざっと見ると、Step3 POST に適切なペイロード データ (破損していない) があることがわかります。gzip ライブラリをもう一度見るように促されます。
解決
.Net クライアントを使用している場合は、設定していない可能性があります。
//This says how many outgoing connection you can make to a single endpoint. Default Value is 2
System.Net.ServicePointManager.DefaultConnectionLimit = 200;
元の質問と回答はこちらです WCF サービスの調整
アップデート:
この構成は、.Net クライアント アプリケーションの起動時またはテストの開始前を除くいつでも使用できます。
さらに、次のように app.config ファイルに含めることもできます
<system.net>
<connectionManagement>
<add maxconnection = "200" address ="*" />
</connectionManagement>
</system.net>
他のヒント
あなたはすでにそれを試してみましたやりなさい場合 - のtry / finallyブロックであなたのサーバー側WCF操作をカプセル化し、それらが実際に戻っていることを確認するためにログを追加します。
これらのオペレーションが完了していることが示された場合は、、その後、私の次のステップは、低いレベルに行き、実際のトランスポート層で見ることであろう。
Wiresharkのか、他の同様のパケットキャプチャツールは、この時点で非常に参考にすることができます。私はこれが標準のポート80
上でHTTPを介して実行されていると仮定していますクライアント上のWiresharkを実行します。あなたがキャプチャを開始オプションでは、tcp http and host service.example.com
するキャプチャフィルタを設定する - これは無関係なトラフィックの量を削減します。
あなたは、あなたのコールの正確な開始時間を通知するようにクライアントを変更することができた場合は、タイムアウトが発生した時間。それとも、密接にそれを監視します。
あなたがエラーを取得した場合、その後、あなたが通話の開始を見つけるために、Wiresharkのログを通じてトロールすることができます。右(/service.svc GETまたはPOST /service.svcのようなものである必要があります)とフォローTCPストリームを選択し、その上に呼び出すクライアントを持つ最初のパケットをクリックしてください。
あなたはWCFは、実際にレスポンスを返送されることを保証することができますので、Wiresharkのは、全体のHTTPの会話をデコードします。
から: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_ .aspxのの
このタイムアウトエラーを回避するために、我々は必要 OperationTimeoutを設定を WCFクライアントでのプロキシのプロパティ コード。この構成は、何かであります そのような他の構成とは異なり、新しいです 送信タイムアウトとして、タイムアウトなどを受け取り、 これは私が早期で議論しました 論文。この操作のタイムアウトを設定するには プロパティの設定は、我々がする必要はあり でIContextChannelに私たちのプロキシをキャスト WCFクライアントアプリケーションを呼び出す前に、 運用契約法ます。
私は非常に同様の問題を抱えています。過去には、これは、シリアル化の問題に関連しています。あなたはまだこの問題を持っている場合、あなたは正確にあなたが戻ってきているオブジェクトをシリアル化できることを確認することができます。あなたが関係を持ってLINQのからSQLへのオブジェクトを使用している場合は、データメンバーとしての参照をバック親オブジェクトとマークに子オブジェクト上の後方参照を置けば具体的に、シリアル化の問題が知られています。
あなたは、シリアル化し、サーバー側でDataContractSerializerを使用して、オブジェクトをデシリアライズし、どんなシリアライズ方法あなたのクライアントが使用するコンソールアプリケーションを書き込むことによって直列化を確認することができます。たとえば、私たちの現在のアプリケーションでは、我々は、WPFやCompact Frameworkの両方のクライアントを持っています。私はDataContractSerializerを使用してシリアライズしてXmlDesserializerを使用してデシリアライズできることを確認するために、コンソールアプリケーションを書きました。あなたはそれを試してみてください。
あなたが子供のコレクションを持っているのLINQからSQLへのオブジェクトを返している場合は、また、あなたは、サーバー側でそれらを熱心にロードされていることを保証しようとするかもしれません。時々、理由遅延読み込みのため、返されるオブジェクトは取り込まれず、要求がサービスメソッドに複数回送信された場合、あなたが見ている動作が発生する可能性があります。
あなたはこの問題を解決した場合は、私はあまりにもそれにこだわっているので、どのように聞いてみたいです。私は途方に暮れてるので、私の問題はシリアル化ではないことを確認しました。
UPDATE:私はそれがすべてのあなたを助けるかはわからないが、サービストレースビューアーツールはちょうどあなたと非常に似たような経験の5日後に私の問題を解決しました。トレースして、生のXMLを見て設定することで、私は自分のシリアル化の問題を引き起こした例外を見つけました。それは、時折、正常シリアライズできるより多くの子オブジェクトを持っていたLINQのツーSQLオブジェクトに関連していました。 web.configファイルに以下を追加すると、トレースを有効にする必要があります:
<sharedListeners>
<add name="sharedListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\Temp\servicetrace.svclog" />
</sharedListeners>
<sources>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
<listeners>
<add name="sharedListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add name="sharedListener" />
</listeners>
</source>
</sources>
結果のファイルは、結果を確認するためにサービストレースビューアツールを使ってか、単にIEで開くことができます。
あなたはリクエスト間でのWCFサービスへの接続を閉じていますか?そうしないと、あなたはこの正確なタイムアウトが表示されます(最終的に)。
私はちょうどproblem.IはApp.configファイル内のノードは間違っconfigedしていることがわかっ解決しました。
<client>
<endpoint name="WCF_QtrwiseSalesService" binding="wsHttpBinding" bindingConfiguration="ws" address="http://cntgbs1131:9005/MyService/TGE.ISupplierClientManager" contract="*">
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="ws" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<**security mode="None">**
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
ノード<security>
であなたの設定を確認し、属性「モード」値が「なし」ではありません。あなたの値が「交通」である場合は、エラーが発生します。
それは、MSDNのブログにあなたにこのリンクを助けるかもしれない:
<のhref = "http://blogs.msdn.com/tess/archive/2009/01/09/net-hang-my-application-hangs-after-i-called-my-wcf-service- A-カップル・オブ・times.aspx」のrel = "nofollowをnoreferrer"> http://blogs.msdn.com/tess/archive/2009/01/09/net-hang-my-application-hangs-after-i -called-MY-WCFサービス・カップル・オブ・times.aspxする
あなたは、メッセージが送信され見に clientVia に使用してみました SOAPツールキットのか、そのようなものを使用していますか?これは、エラーは、クライアント自体からか、どこか別の場所から来ているかどうかを確認するのに役立つ可能性があります。
あなたはWCFトレースをチェックしましたか? WCFは、例外を飲み込むだけエンドポイントは意味のある何も返さなかったので、あなたが取得しているタイムアウトで最後の例外を返す傾向があります。
enum MyEnum{ a=1, b=2};
また、このエラーが表示されます> この例外メッセージは非常に汎用的で、さまざまな理由のために受け取ることができるように見えます。 Windowsの8.1のマシンにクライアントを展開しながら、私たちはこれに走りました。私たちのWCFクライアントがWCFサービスをWindowsサービスの内部で実行され、継続的にポーリングします。 Windowsサービスは、管理者以外のユーザーで実行されます。問題はパススルーし、次のように認証を許可するようにWCF構成での「Windows」にclientCredentialTypeを設定することで修正されました。
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
私は、WCFの専門家ではないが、あなたはIIS上のDDOS保護に実行されていない場合、私は思ったんだけど。 私はあなたには、いくつかの時点で、サーバに単一のクライアントからの同時接続の束を実行する場合、サーバーは、それがDDOS攻撃を疑うよう呼び出しに応答を停止することを経験から知っています。 また、彼の攻撃にクライアントを遅くするために、彼らはタイムアウトになるまで開いている接続を保持します。
複数の接続が異なるマシンから来る/ IPのは、しかし、問題になることはありません。
このMSDNの記事で詳細があります:
http://msdn.microsoft.com/en-us/library /bb463275.aspxする
MaxConcurrentSessionのspropertyをチェックします。