web-dev-qa-db-ja.com

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

IIS7で実行されているWCFサービス(* .svc)と、サービスを照会するさまざまなクライアントを持つアプリケーションがあります。サーバーはWin 2008サーバーを実行しています。クライアントは、Windows 2008 ServerまたはWindows 2003サーバーのいずれかを実行しています。次の例外が発生しています。これは、実際には多数の潜在的な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 and http and http.request.method eq POST」に拡張し、このストリーム中に6つのPOSTを見ました。これは奇妙に思えたので、tcp.stream eq 100などの別のストリームで確認しました。3つのPOSTがありました。ただし、すべてのWCF呼び出しの後に接続を閉じるので、ストリームごとに1つの呼び出しが必要になります(ただし、TCPについてはあまり知りません)。

もう少し調べて、これらの6つの呼び出しがどこにあるのかを調べるために、httpパケットの負荷をディスクにダンプしました。

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ライブラリをもう一度見るように私を押します。

94
Jason Kealey

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

まだ試していない場合-サーバー側のWCF操作をtry/finallyブロックにカプセル化し、ログを追加して実際に返されるようにします。

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

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

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

可能であれば、クライアントを変更して、コールの正確な開始時間とタイムアウトが発生した時間を通知します。または、厳密に監視してください。

エラーが発生した場合、Wiresharkログをトロールして、コールの開始を見つけることができます。クライアントが呼び出している最初のパケットを右クリックし(GET /service.svcまたはPOST /service.svc)のようなものである必要があります)、[フォローTCPストリーム。

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

3
user111013

from: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

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

2
Joel Martinez

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

2
aridlehoover

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

サーバー側のDataContractSerializerとクライアントが使用するシリアル化方法を使用してオブジェクトをシリアル化および逆シリアル化するコンソールアプリを記述することで、シリアル化を確認できます。たとえば、現在のアプリケーションには、WPFとCompact Frameworkの両方のクライアントがあります。 DataContractSerializerを使用してシリアル化し、XmlDesserializerを使用して逆シリアル化できることを確認するコンソールアプリを作成しました。試してみてください。

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

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

更新:それがあなたに役立つかどうかはわかりませんが、Service Trace Viewer Toolは、あなたと非常によく似た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 Toolを使用して開くか、IEで開いて結果を確認できます。

2
Brett Bim

問題を解決したところ、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」の場合、エラーが発生します。

2
alexanderlc
1
Rakoun

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

0
Miki Watts

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

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

このMSDN投稿には詳細があります。

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

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

0
jurgenb

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

0
tim

この例外メッセージは非常に一般的であり、さまざまな理由で受信される可能性があります。クライアントを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

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

0
Philippe