WCFタイムアウト例外の詳細な調査


94

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から送信され、接続を切断しています。私が受け取る例外レポートは、Step3タイムアウトからのものです。

私は、tcpストリーム「tcp.stream eq 192」を見て、これを発見しました。次に、フィルターを「tcp.stream eq 192およびhttpおよびhttp.request.method eq POST」に拡張し、このストリーム中に6つのPOSTを確認しました。これは奇妙に思えたので、tcp.stream eq 100などの別のストリームで確認しました。3つのPOSTがありました。ただし、すべての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ライブラリを見るように促します。


ジェイソン-この問題を解決したことはありますか?それはDefaultConnectionLimit設定でしたか?
SFun28、2011年

2
@JasonKealey-他の多くの質問とは対照的に、質問を投稿する前に自分で試していないと非難することはできません:)私はあなたの質問がとても詳細であり、すべての重要な詳細が含まれているのが大好きです。私は解決策が同様に同じであると思いますので、あなたは、非常に私のようなルックスを記述する症状:)
ØyvindBråthen

回答:


51

.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>

これは有望に見えます。次のスケーラビリティテストでテストするためにこれを含めました。それはクラッシュするようなランダム設定のように見えます:)ポインタをありがとう。
Jason Kealey、2010

1
@ジェイソン:サーバープログラマーであれば、サーバーのスケーラビリティを維持することがどれほど重要であるか、また、上記を使用した後でも並行性の問題に現在苦しんでいる人も知っています。あなたが次の質問stackoverflow.com/questions/2637175/wcf-network-costを簡単に見ることができるなら、私はクライアントとサーバーの間の31msの待ち時間で苦しんでいて、それを減らす必要があります。
Mubashar

3
わずか1年で完了しましたが、このフラグを設定して、アプリケーションで別のストレステストを実行しました。問題は解決したようですので、最良の回答をさせていただきます。これが必要な最後のパズルのピースであったことは驚くことではありませんが、エラーが発生しないようにするために他のすべての要素を配置する必要がありました。どうもありがとう!
Jason Kealey、2011

2
@Aris:.netクライアントアプリケーションで、起動時またはグローバル構成を設定した場所で、構成可能にしたい場合は、次のように構成ファイルに追加できます<system.net> <connectionManagement> <add maxconnection = "200" address = "*" /> </ connectionManagement> </system.net>
Mubashar 14

3

まだ試していない場合は、サーバー側のWCF操作をtry / finallyブロックにカプセル化し、実際に戻ってくることを確認するためのログを追加します。

それらが操作が完了していることを示している場合、私の次のステップは、より低いレベルに移動し、実際のトランスポート層を調べることです。

この時点では、Wiresharkまたは他の同様のパケットキャプチャツールが非常に役立ちます。これは標準ポート80でHTTPを介して実行されていると想定しています。

クライアントでWiresharkを実行します。キャプチャを開始するときのオプションで、キャプチャフィルターをに設定しtcp http and host service.example.com ます。これにより、無関係なトラフィックの量が減少します。

可能であれば、クライアントを変更して、コールの正確な開始時刻とタイムアウトが発生した時刻を通知します。または、それを注意深く監視します。

エラーが発生した場合は、Wiresharkログを調べて、通話の開始を見つけることができます。クライアントが呼び出している最初のパケット(GET /service.svcまたはPOST /service.svcのようなものでなければなりません)を右クリックし、[Follow TCP Stream]を選択します。

WiresharkはHTTP会話全体をデコードするため、WCFが実際に応答を返送していることを確認できます。


サーバーにログオンしていますが、エラーは発生していません。今、WireSharkを実行して、見つけられるものを確認しています。大量のトラフィックがあることを考えると、分析するのは面倒ですが、何か見つけたら報告します。
Jason Kealey、2009年

私は過去6時間にわたってWireSharkを実行し、約60kフレームを収集しました。今日、このクライアントから報告された例外は1つだけです。RST(リセット)とマークされたTCP接続を確認しました。どうやら、エラー電子メールを送信した後のことです。おそらく、接続を終了しているWCFです。ペイロード(525k)をディスクに保存しました。私は、同様のサイズのペイロードを持つ87個の他の呼び出しがあることを確認しました。私はいくつかのTCP再送信を確認しましたが、他の呼び出しでもいくつか確認しました(失敗しませんでした)。私のネットワーキングハードウェア+ケーブルについて不思議に思っています。
Jason Kealey、2009年

ローカルネットワーク上でも、TCP再送信の存在は必ずしも悪いことではありません。2つのエンドポイントを1つのスイッチに物理的に接続することが可能である場合、それは試してみる価値があるかもしれませんが、それが修正されることを期待しません。可能な場合-トラフィックをサーバーとの間でやり取りするだけで、他には何も渡さない非常に基本的なクライアントアプリケーションを作成します。これにより、タイムアウトを引き起こす可能性のあるアプリケーションの問題を排除できます。

また、TCPリセットパケットの表示についても言及しました-サーバーはその時点でなんらかの応答を配信しましたか(または、それ以上のデータを待っていましたか?)RSTと前のパケットの間にかなりの遅延がありましたか?

サーバーはリモートです。ローカルでテスト環境を作成して、それが役立つかどうかを確認する予定です。RSTについては、最後の5回のTCP再送信から34秒後に送信されました。(再送信の間隔は1〜8秒)。手がかりはありますか?
Jason Kealey、2009年

2

から:http : //www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

このタイムアウトエラーを回避するに は、WCFクライアントコードでプロキシのOperationTimeoutプロパティを構成する必要があります。この構成は、送信タイムアウト、受信タイムアウトなど、記事の前半で説明した他の構成とは異なり、新しいものです。この操作タイムアウトプロパティの構成を設定するには、操作コントラクトメソッドを呼び出す前に、プロキシをWCFクライアントアプリケーションのIContextChannelにキャストする必要があります。


私はこれを試しました。タイムアウトに関係なく、タイムアウトは発生しますが、操作がそれほど長くなく、同じクエリを実行する他のすべてのクライアントがこの時間中に機能するため、これは意味がありません。
Jason Kealey、2009年

私のテストでは、OperationTimeoutが構成のReceiveTimeoutを単にオーバーライドしていることが証明されました。したがって、それは何の役にも立ちません。
dudeNumber4 2012年

2

非常によく似た問題が発生しています。過去には、これはシリアライゼーションの問題に関連していました。この問題が引き続き発生する場合は、返されるオブジェクトを正しくシリアル化できることを確認できますか。具体的には、リレーションシップを持つLinq-To-Sqlオブジェクトを使用している場合、子オブジェクトの親オブジェクトへの後方参照を配置し、その後方参照をDataMemberとしてマークすると、シリアル化に関する既知の問題があります。

サーバー側のDataContractSerializerとクライアントが使用するシリアル化メソッドを使用してオブジェクトをシリアル化および逆シリアル化するコンソールアプリを作成することで、シリアル化を確認できます。たとえば、現在のアプリケーションには、WPFクライアントとCompact Frameworkクライアントの両方があります。コンソールアプリを作成して、DataContractSerializerを使用してシリアル化し、XmlDesserializerを使用して逆シリアル化できることを確認しました。あなたはそれを試すかもしれません。

また、子コレクションを持つLinq-To-Sqlオブジェクトを返す場合は、サーバー側で熱心にロードしたことを確認してみてください。ときどき、遅延読み込みのために、返されるオブジェクトにデータが入力されず、リクエストがサービスメソッドに複数回送信される場所にある動作が発生する場合があります。

あなたがこの問題を解決したなら、私もそれで立ち往生しているので、私はその方法を聞きたいです。私の問題がシリアル化ではないことを確認したので、途方に暮れています。

更新:それがあなたに役立つかどうかはわかりませんが、Service Trace Viewerツールは、あなたと非常によく似た体験を5日間行った後、私の問題を解決しました。トレースを設定してから生のXMLを調べると、シリアル化の問題の原因となっている例外が見つかりました。これは、正常にシリアル化できる数よりも多くの子オブジェクトが存在することがあるLinq-to-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>

結果のファイルは、Service Trace Viewerツールを使用して、またはIEで開くだけで、結果を確認できます。


2

リクエスト間でWCFサービスへの接続を閉じていますか?そうしないと、(最終的に)この正確なタイムアウトが表示されます。


2

私は問題を解決しました。App.configファイルのノードが正しく構成されていないことがわかりました。

<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>属性「モード」の値は「なし」です。値が "Transport"の場合、エラーが発生します。


これはセキュリティに影響しませんか?もしそうなら、これはほとんどの実際のアプリケーションの解決策ではないかもしれません
Veverke

0

SOAPツールキットなどを使用して、送信されたメッセージを表示するためにclientViaを使用してみましたか?これは、エラーがクライアント自体から発生したのか、それとも別の場所から発生したのかを確認するのに役立ちます。


この情報をWCF呼び出しで簡単に記録できるようにする、非推奨のSOAPツールキットよりも新しいツールを知っていますか?
Jason Kealey、2009年

SOAP Toolkitdeprecated
Kiquenet、2015年

0

WCFトレースを確認しましたか?エンドポイントは意味のあるものを何も返さなかったので、WCFは例外を飲み込み、最後の例外(返されているタイムアウト)だけを返す傾向があります。


私はSvcTraceViewerを試しましたが、それが報告した唯一の例外は(クライアントでの)タイムアウトでした。サーバーで何も報告されていません。
Jason Kealey、2009年

トレースのすべてのオプションを開きます。すべてのトレースオプションを開いているとは限りません。また、イベントトレースファイルとメッセージトレースファイルの両方を確認してください。
三木ワット

0

また、デフォルトで設定されていないenum型のプロパティを含むオブジェクトをクライアントに返し、そのenumに0にマップする値がない場合にも、このエラーが発生します。 enum MyEnum{ a=1, b=2};


0

この例外メッセージは非常に一般的であり、さまざまな理由で受信される可能性があるようです。Windows 8.1マシンにクライアントをデプロイしているときに、これに遭遇しました。WCFクライアントはWindowsサービス内で実行され、WCFサービスを継続的にポーリングします。Windowsサービスは、非管理者ユーザーで実行されます。この問題は、次のように、WCF構成でclientCredentialTypeを "Windows"に設定して、認証がパススルーできるようにすることで修正されました。

      <security mode="None">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>

0

私はWCFの専門家ではありませんが、IISでDDOS保護を実行していないのではないかと思います。経験から、単一のクライアントからサーバーへの多数の同時接続を実行すると、サーバーがDDOS攻撃の疑いがあるため、呼び出しへの応答を停止することがわかっています。また、クライアントの攻撃を遅らせるために、タイムアウトになるまで接続を開いたままにします。

ただし、異なるマシン/ IPからの複数の接続は問題になりません。

このMSDNの投稿には、より多くの情報があります。

http://msdn.microsoft.com/en-us/library/bb463275.aspx

MaxConcurrentSessionプロパティを確認してください。


私が見たすべてから、これが起こっていると感じていますが、(サーバー上で)持っています:<serviceThrottling maxConcurrentCalls = "150" maxConcurrentInstances = "150" maxConcurrentSessions = "150" /> <serviceDebug includeExceptionDetailInFaults = "true" />これが発生しているかどうかを確認するために監視できるパフォーマンスモニターまたはIISログはありますか?
Jason Kealey、2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.