WCF - Случайное время ожидания клиента при совершении нескольких вызовов
у меня есть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, и размер тела сообщения в порядке (~ 50 КБ) и99% запросов возвращаются через секунду или две, Отлично!
Однако, почти с каждой итерацией, есть один вызов в связке, который занимает минуты, и я не знаю почему ... МойsendTimeOut
на клиенте было на 1 минуте и естественно, что один звонок потерпит неудачу. Я продлил его до 10 минут, и звонок, кажется, завершается чуть более чем за 2 минуты - хотя иногда это занимало бы еще больше времени. Проблема кажется очень случайной - это может быть первый звонок, это может быть 30-й звонок. Но это очень воспроизводимо.
Я разместил некоторые записи о вызове хранимой процедуры в методе службы WCF, и он выполняет и возвращает данные менее чем за секунду. Так что я не думаю, что это проблема с базой данных.
Используя 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, и, на первый взгляд, нет ошибок или предупреждений, но я не могу понять, на что я смотрю, кроме основ.
Как мне понять, в чем и где проблема? Это сериализация? Это проблема сети? Может ли сервер не поспевать за тем, чтобы клиент отправлял так много запросов?
Я попытался настроить регулирование WCF в файле конфигурации, добавив соответствующий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)