でホストされているサービスWPF
を介してデータを要求しているクライアントがいます。サービス メソッドは、データを取得するためにストアド プロシージャ ( ) を呼び出します。WCF
IIS 7
SQL 2012
EF
ロードするデータが大量にあるため、クライアントは、データのロードを「分割」して大きなペイロードとタイムアウトを回避するために、サービス メソッドを複数回呼び出します。
生成されたサービス プロキシを使用します。System.ServiceModel.ClientBase<T>.
また、バイナリ エンコーディングを使用したカスタム http バインディングも使用しています (ここから)。実際の実装は次のとおりです。
<customBinding>
<binding name="CustomBinding_IPointDataAccess" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00">
<binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" maxSessionSize="2048">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" />
</binding>
また、IIS では動的圧縮がオンになっています。Fiddler でリクエストを表示できます。メッセージの本文のサイズは問題なく (~50KB) 、リクエストの 99% は 1 ~ 2 秒で返されます。完全!
ただし、ほとんどすべての反復で、完了するまでに数分かかる呼び出しが 1 つあります。その理由はわかりません...sendTimeOut
クライアントでの私の呼び出しは 1 分で、当然その 1 つの呼び出しは失敗します。私はそれを 10 分に延長しました。通話は 2 分強で完了するように見えますが、場合によってはそれ以上かかることもあります。問題は非常にランダムに発生します。最初の呼び出しである可能性もあれば、30 回目の呼び出しである可能性もあります。しかし、それは非常に再現性があります。
WCF サービス メソッドのストアド プロシージャ呼び出しの周りにログを配置し、実行して 1 秒以内にデータを取得しました。したがって、データベースの問題ではないと思います。
Fiddler を使用すると、問題のある呼び出しによって次のような出力が生成されます。
ACTUAL PERFORMANCE
--------------
ClientConnected: 14:02:42.959
ClientBeginRequest: 14:03:01.224
GotRequestHeaders: 14:03:01.224
ClientDoneRequest: 14:03:01.574
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 46ms
HTTPS Handshake: 0ms
ServerConnected: 14:05:16.021
FiddlerBeginRequest: 14:05:16.021
ServerGotRequest: 14:05:16.021
ServerBeginResponse: 14:03:04.784
GotResponseHeaders: 14:05:16.561
ServerDoneResponse: 14:05:16.611
ClientBeginResponse: 14:05:16.611
ClientDoneResponse: 14:05:16.611
ServerBeginResponse
との間のかなりの時間に注意してくださいGotResponseHeaders
。これは、ここで見られる問題と非常によく似ているようです。
私は WCF Service Tracing を有効にしました。一見すると、エラーや警告はありませんが、基本を超えて見ているものをあまり理解できません。
問題の内容と場所を突き止めるにはどうすればよいですか? シリーズ化ですか?ネットワークの問題ですか?サーバーは、クライアントが送信する大量のリクエストに対応できませんか?
適切な を追加して、構成ファイルの WCF Throttling を調整しようとしましたserviceBehaviors
が、違いはありませんでした。
私は VPN 接続を介してこれを行っていることに言及する必要がありますが、ファイル転送、リモート デスクトップ接続などの他のことは問題なく機能します。かなり信頼できそうです。
必要に応じて詳細を提供できます。
編集 (6.10.2013):これが関連しているのか、単なるまぐれなのかはわかりませんが、問題のある呼び出しで、ボディのサイズが他のものよりも大幅に小さいことに気付きました。これは毎回ではありませんが、いくつかの手がかりが得られる場合があります。以下は、Fiddler からのスクリーン キャプチャで、呼び出しごとにボディ サイズがどの程度一貫していなければならないかを示しています。選択したエントリ (#21) は、サイズが他のエントリよりもはるかに小さいですが、完了するまでに 2 分以上かかります。
奇妙なことに、今回は例外が発生しました。例外は毎回発生しません。
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)