94

IIS7で実行されているWCFサービス(* .svc)と、サービスをクエリしているさまざまなクライアントを持つアプリケーションがあります。サーバーはWin2008Serverを実行しています。クライアントは、Windows2008ServerまたはWindows2003サーバーのいずれかを実行しています。次の例外が発生しています。これは、実際には、多数の潜在的な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.streameq192」を見て発見しました。次に、フィルターを「tcp.streameq192およびhttpおよびhttp.request.methodeqPOST」に拡張し、このストリーム中に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ライブラリをもう一度見るように私をプッシュします。

4

11 に答える 11

52

.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>
于 2010-04-16T11:24:41.530 に答える
3

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

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

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

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

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

エラーが発生した場合は、Wiresharkログをトロールして、通話の開始を見つけることができます。クライアントが呼び出している最初のパケット(GET/service.svcまたはPOST/service.svcなど)を右クリックし、[FollowTCPStream]を選択します。

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

于 2009-06-17T17:05:47.587 に答える
2

差出人:http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx

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

于 2009-06-11T15:22:05.627 に答える
2

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

サーバー側のDataContractSerializerと、クライアントが使用するシリアル化方法を使用してオブジェクトをシリアル化および逆シリアル化するコンソールアプリを作成することで、シリアル化を確認できます。たとえば、現在のアプリケーションには、WPFクライアントとCompactFrameworkクライアントの両方があります。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で開いて結果を調べることができます。

于 2009-08-20T14:55:30.347 に答える
2

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

于 2011-04-04T22:54:13.473 に答える
0

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

于 2009-06-15T12:27:48.987 に答える
0

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

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

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

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

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

于 2009-06-16T07:10:39.460 に答える
0

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

于 2009-06-16T08:31:50.153 に答える
0

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

于 2011-02-25T22:54:57.620 に答える
0

問題を解決しました。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>で構成を確認します。属性「mode」の値は「None」です。値が「Transport」の場合、エラーが発生します。

于 2011-11-18T07:31:40.190 に答える
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>
于 2014-06-13T15:57:24.450 に答える