У нас есть приложение с сервисом WCF (* .svc), работающим на IIS7, и различными клиентами, запрашивающими сервис. Сервер работает под управлением Win 2008 Server. Клиенты работают под управлением Windows 2008 Server или Windows 2003 server. Я получаю следующее исключение, которое, как я видел, на самом деле может быть связано с большим количеством потенциальных проблем 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, это все равно происходит время от времени. В большинстве случаев таймаутов нет, но я получаю несколько раз в час. Ошибка происходит от любого из методов, которые вызываются. Один из этих методов не имеет параметров и возвращает немного данных. Другой принимает много данных в качестве параметра, но выполняется асинхронно. Ошибки всегда происходят от клиента и никогда не ссылаются на какой-либо код на сервере в трассировке стека. Всегда заканчивается:
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 минуту. Глядя на трассировку на стороне сервера, я вижу, что сервер не знает об этом исключении. Максимальная продолжительность, которую я вижу, составляет 10 секунд.
Я просмотрел активные подключения к базе данных, используя exec sp_who
на сервере. У меня есть только несколько (2-3). Я посмотрел на TCP-соединения от одного клиента, используя TCPview. Обычно это около 2-3, а я видел до 5 или 6.
Проще говоря, я в тупике. Я перепробовал все, что мог найти, и, должно быть, упускаю что-то очень простое, что сможет увидеть эксперт WCF. Я чувствую, что что-то блокирует моих клиентов на низком уровне (TCP) до того, как сервер фактически получит сообщение, и / или что что-то ставит сообщения в очередь на уровне сервера и никогда не позволяет им обрабатываться.
Если у вас есть счетчики производительности, на которые я должен посмотреть, пожалуйста, дайте мне знать. (пожалуйста, укажите, какие значения плохие, так как некоторые из этих счетчиков трудно расшифровать). Кроме того, как я могу записать размер сообщения WCF? Наконец, есть ли там какие-нибудь инструменты, которые позволили бы мне проверить, сколько соединений я могу установить между моим клиентом и сервером (независимо от моего приложения)
Спасибо за ваше время!
Дополнительная информация добавлена 20 июня:
Мое приложение WCF выполняет что-то похожее на следующее.
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
Используя WireShark, я увидел, что при возникновении ошибки у меня есть пять повторных передач TCP, за которыми следует сброс TCP позже. Я предполагаю, что RST исходит от WCF, убивающего соединение. Сообщение об исключении, которое я получаю, связано с тайм-аутом Step3.
Я обнаружил это, посмотрев поток tcp "tcp.stream eq 192". Затем я расширил свой фильтр до «tcp.stream eq 192 и http и http.request.method eq POST» и увидел 6 POST во время этого потока. Это казалось странным, поэтому я проверил с другим потоком, таким как tcp.stream eq 100. У меня было три POST, что кажется немного более нормальным, потому что я делаю три вызова. Тем не менее, я закрываю свое соединение после каждого вызова WCF, поэтому я ожидал одного вызова на поток (но я не очень разбираюсь в TCP).
Исследуя немного больше, я сбросил загрузку http-пакета на диск, чтобы посмотреть, что и где эти шесть вызовов вызывают.
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
Я предполагаю, что два одновременно работающих клиента используют одно и то же соединение, поэтому я видел дубликаты. Однако у меня все еще есть несколько проблем, которые я не могу понять:
а) Почему пакет поврежден? Случайная случайность сети - возможно? Загрузка распаковывается с использованием этого примера кода: http://msdn.microsoft.com/en-us/library/ms751458.aspx - Может ли код время от времени глючить при одновременном использовании? Я должен проверить без библиотеки gzip.
b) Почему я вижу, что шаг 1 и шаг 2 выполняются ПОСЛЕ истечения времени ожидания поврежденной операции? Мне кажется, что эти операции не должны были произойти. Возможно я не смотрю на правильный поток, потому что мое понимание TCP неверно. У меня есть другие потоки, которые происходят одновременно. Я должен исследовать другие потоки - быстрый взгляд на потоки 190-194 показывает, что в Step3 POST имеются правильные данные полезной нагрузки (не поврежденные). Подталкивает меня снова посмотреть библиотеку gzip.