Windows Server2008R2仮想マシンで実行されているWCFデータ収集サービスがあります。クライアントはWin7x64ボックスであり、アプリケーションはC#.NET4Windowsフォームアプリです。このサービスの主な目的は、クライアントからテスト結果を収集し、そのデータに基づいてレポートを提供することです。(SQL ServerインスタンスおよびOracleインスタンスにインターフェイスしますが、それはおそらく無関係です。)
最近、クライアントを追加すると、データ送信が失われ、サービス側で「MaxOutboundConnectionsPerEndpointクォータ(10)に達しました」というエラーが表示されるようになったため、それに応じてパラメーターを調整しました。
このタイプのエラーはなくなりましたが、サーバー側で「FaultedSystem.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel」エラーが発生しています。サーバー側でWireSharkを実行すると、実行が継続されないため、無駄な作業であることがわかりました。VMが干渉した可能性がありますが、わかりません。
クライアント側でWireSharkを実行すると、より多くの情報が得られました。送信エラーが発生すると、WireSharkはいくつかの「TCPウィンドウフル」エラーを報告しました。
サーバー側からのバインディング定義は次のとおりです。
<bindings>
<netTcpBinding>
<binding name="bigBufferBinding"
portSharingEnabled="false"
maxBufferSize="1024000"
maxBufferPoolSize="1000000"
maxReceivedMessageSize="1024000"
maxConnections="500"
listenBacklog="250"
sendTimeout="00:05:00"
receiveTimeout="00:05:00">
<readerQuotas maxDepth="200"
maxStringContentLength="65536"
maxArrayLength="32768"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
そして、これがクライアント側です。
<bindings>
<netTcpBinding>
<binding name="bigBuffer_ClientTcpBinding"
maxBufferSize="1024000"
maxBufferPoolSize="1000000"
maxReceivedMessageSize="1024000"
sendTimeout="00:00:30"
receiveTimeout="00:00:30">
<readerQuotas maxDepth="200"
maxStringContentLength="65536"
maxArrayLength="32768"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
maxBufferSize、maxBufferPoolSize、およびmaxReceivedMessageSize属性を増やしてみましたが、大幅に増やすとサービスの開始に失敗しました。とにかく問題がどこにあるのかわかりません。
ここで何を見る必要がありますか?大量のデータがないため(10クライアントが散発的に60〜40000バイトのデータをサービスに送信します)、WCFサービスを圧倒することはありません。TCPの設定方法と関係があると思いますが、それは単なる推測です。ジャンボパケットが無効になっているギガビットネットワーク上で実行されています。
数千回の試行のうち、1日あたり15〜40回のデータ障害が発生しています。再試行を追加して、データが最終的にそこに到達するようにしました(ほとんどの場合、2回目の試行)。これで問題は実際には解決されませんが、本番環境が失われ、実際にデータが失われることはありません。
予想される抗議と叱責を鎮めるために、失敗時にシリアル化されたデータをディスクファイルに書き込んでいるので(2回!)、データがデータベースに到達できない場合は、再送信できます。実際にデータを失うことはありませんでした。
アイデア?助けていただければ幸いです。リクエストに応じて、より多くのデータを利用できます。
ありがとう、デイブ