2010-06-09 3 views
21

У нас есть куча сервисов WCF, которые работают почти все время, используя различные привязки, порты, максимальные размеры и т. Д. Супер-разочаровывающая вещь о WCF заключается в том, что когда она (редко) мы бессильны выяснить, почему это не удалось. Иногда вы получите сообщение, которое выглядит следующим образом:WCF таймауты - это кошмар

System.ServiceModel.CommunicationException: Подключение гнездо было прервано. Это может быть вызвано ошибкой , обрабатывающей ваше сообщение или принимающим тайм-аутом, превышающим пул хост или базовую сеть проблема с ресурсами. Локальный тайм-аут гнезда был «01: 00: 00». ---> System.IO.IOException: Не удалось прочитать данные транспортного сообщения: существующее соединение было принудительно закрыто удаленным хостом.

Проблема в том, что локальный тайм-аут, который он дает вам, является просто попыткой быть удобным. Это может быть или не быть причиной проблемы. Но хорошо, иногда сети имеют проблемы. Ничего страшного. Мы можем повторить или что-то еще. Но вот огромная проблема. Помимо того, что вы не указали, какой именно тайм-аут (если таковой имеется) привел к сбою («ваш тайм-аут получения на стороне сервера был превышен» или что-то еще, было бы полезно), WCF, похоже, имеет два типа тайм-аутов.

Timeout Тип # 1) тайм-аут, что, если увеличивается, что увеличивает шансы на успех вашей операции. Итак, соответствующий тайм-аут - час, вы загружаете огромный файл, который займет час и двадцать минут. Это не удается. Вы увеличиваете таймаут, он преуспевает. У меня нет никаких проблем с этим типом таймаута.

Timeout Тип # 2) таймаут, который просто определяет, как долго вы должны ждать, пока сервис на самом деле сбой и выдаст сообщение об ошибке, но изменения значения тайм-аута не имеет никакого влияния на шанс успех. В основном, что-то происходит в течение первой секунды запроса на обслуживание, которое заманивает вещи. Он никогда не восстановится. WCF не волшебным образом повторяет подключение к сети. Прекрасно, иногда установление сетевого соединения идет не так. Но если ваш тайм-аут составляет 2 часа, вы должны подождать 2 целых часа без каких-либо шансов на это, прежде чем он наконец признает, что он не работает и дает вам ошибку.

Но ошибка, которую вы видите в обоих случаях, выглядит одинаково. С таймаутом Type # 2 все еще выглядит так, как будто вы запускаете тайм-аут. Но вы можете увеличить все ваши таймауты до 4 лет, и все, что он сделал бы, - это сделать 4 года, чтобы получить сообщение об ошибке. Я знаю, что Type # 2 существует, потому что я могу выполнить операцию, которая, как известно, завершается менее чем за минуту, когда она удалась, и потребовалось 2 часа, чтобы сработаться. Но, если я убью его и повторю, он быстро завершается. (Если вам интересно, почему может потребоваться 2-часовой тайм-аут для операции, которая занимает меньше минуты, есть моменты, когда я запускаю операцию с гораздо большим файлом, и это может занять более часа.)

Итак, для борьбы с проблемой с типом # 2 вы хотите, чтобы ваш тайм-аут был действительно быстрым, чтобы вы сразу узнали, есть ли проблема. Затем вы можете повторить попытку. Но непреодолимой проблемой является то, что, поскольку я не знаю, какие таймауты являются причиной сбоя, я не знаю, какие тайм-ауты являются Type # 1, а какие - Type # 2. Может быть один тайм-аут (скажем, тайм-аут отправки на стороне клиента), который действует как тип # 1 в некоторых случаях и тип # 2 в других. Я понятия не имею, и у меня нет способа узнать.

Кто-нибудь знает, как отследить таймауты Type # 2, чтобы я мог установить их на низкие значения без необходимости сокращать фактические (читай: Тип # 1) таймауты и понижать вероятность успеха?

спасибо.

Разъяснение Тип # 2 таймаутов в ответ на комментарий Эндрю Андерсон:

Моя вера в том, что что-то идет не так, между запросом клиента и код, начинающийся выполнить на сервере. Во всех случаях, когда код сервера указывает на частичный прогресс, он никогда не завершил какую-либо операцию, не закончив все это. Таким образом, серверный код никогда не запускается, и сколько времени потребуется для выполнения, не имеет значения (кроме того, что это влияет на то, что мы устанавливаем наши значения тайм-аута в первую очередь для его размещения).

+1

Уточнение запроса по таймауту 2-го типа: что не удается? Код служебной стороны или что-то среднее между запросом соединения с клиентом и фактическим запуском вашего вызова метода со стороны службы? –

+0

Можете ли вы дать простое пошаговое описание этих «Тип 2» -местерионов и точную конфигурацию привязки, на которую вы ссылаетесь? – Alex

+0

Эта проблема аналогична управлению проектами (как клиенты) и разработчикам (как услуги). В любое время, превышающее тайм-аут, управление проектами хочет знать, является ли это типом 1 или типом 2. Однако разработчики не знают (они еще не закончены), и поэтому не могут советовать. –

ответ

3

Я всегда добавляю сообщение «сердцебиение» в своих давно работающих службах WCF. Затем вы можете установить таймауты Type # 1 на низкое значение (в 2-3 раза больше частоты звонка), а таймауты Type # 2 становятся очевидными.

+0

Можете ли вы уточнить? Похоже, вы либо можете выделить таймауты Type # 1 (которых я не знаю), либо у вас как-то есть длительные службы WCF, которые работают, когда ВСЕ ваши таймауты установлены на небольшие значения. Как вы это достигаете? –

+0

Собственно, после повторного чтения вашего вопроса я бы сказал, что обратный вызов - это все, что вам может понадобиться (так что вы получите односторонний запрос, который в какое-то время отвечает на односторонний обратный вызов). Сердцебиение все равно будет необходимо для предотвращения тайм-аутов ожидания в ожидании запроса. –

+0

Я думаю, вы считаете, что односторонний запрос успешный, а код на стороне сервера (обработка запроса) является виновником. См. Разъяснение комментария Андрея в моем редактировании - я не думаю, что это проблема. Я думаю, что односторонний запрос так же неудачен, как и полноценная операция. –

0

Чтобы узнать, какой конкретный тайм-аут вызвал тайм-аут или другую ошибку, настройте и используйте tracing.

0

У меня такая же проблема, и это было связано с плохой аппаратурой, и ее было очень сложно отлаживать, а также с wirehark (tcp сниффер), пакеты не отображали каких-либо конкретных ошибок, мы обнаружили некоторые tcp -рецепты, и это могло быть симптомом, но на самом деле пакеты просто застряли где-то внутри модема-маршрутизатора, который был модемом связи (pirelli gate 2 plus), после изменения модема/маршрутизатора проблема полностью исчезла.

В любом случае мы выяснили, что wsHttpBinding через http, он более надежный для подключения к Интернету, где у вас нет контроля, и вы не можете быть уверены в том, какое оборудование установлено на сайте.

Надеется, что это может помочь и кто-то еще :)

0

Убедитесь, что вы правильно обработками исключений обслуживания. Вы часто получаете соединения, которые выпадают без причины, если исключения неправильно обрабатываются. Кроме того, если они делают, и они обрабатываются корректно, вы можете нормально получить больше полезной информации:

https://msdn.microsoft.com/en-us/library/ms733721(v=vs.110).aspx

Кроме того, использование «Heartbeat» или регулярный метод звона, который вы можете вызвать у клиента. Я обнаружил, что у маршрутизаторов клиентов есть автоматический тайм-аут, встроенный в TCP-соединения, которые он использует для завершения простоя соединений. Без метода heartbeat клиентский маршрутизатор может преждевременно прекратить соединение, которое не будет затронуто настройками службы WCF.