У нас є програма, яка має службу WCF (* .svc), що працює на IIS7, і різні клієнти, які запитують послугу. На сервері працює Win 2008 Server. Клієнти працюють або на сервері Windows 2008, або на сервері Windows 2003. Я отримую наступний виняток, який, як я бачив, насправді може бути пов’язаний із великою кількістю потенційних проблем 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.
б) Чому я бачу, як кроки 1 та 2 виконуються ПІСЛЯ закінчення пошкодженої операції? Мені здається, ніби ці операції не мали відбуватися. Можливо, я не дивлюсь на правильний потік, оскільки моє розуміння TCP є хибним. У мене є інші потоки, які відбуваються одночасно. Мені слід дослідити інші потоки - короткий огляд потоків 190-194 показує, що в Step3 POST є належні дані корисного навантаження (не пошкоджені). Підштовхуючи мене знову поглянути на бібліотеку gzip.