Отслеживание WCF. Как я могу получить точную причину закрытия соединения? - PullRequest
11 голосов
/ 19 декабря 2009

В моей службе WCF при попытке передачи больших данных я постоянно получаю сообщение об ошибке: Основное соединение было закрыто: соединение было неожиданно закрыто

Я хочу знать, какая именно причина вызывает эту ошибку, поэтому я настроил Отслеживание WCF и могу прочитать traces.svclog файл.

Проблема в том, что я вижу в этом файле много информации о потоке процессов, я вижу точное время появления исключения, но не вижу точной причины этого. Это из-за MaxReceivedMessageSize или что-то в этом роде.

Неужели traces.svclog не может содержать такую ​​информацию или я что-то не так делаю?

Как получить такую ​​информацию?

Отредактировано (добавлено):

Из моего серверного app.config:

    <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="NAVBinding_ICustomer_Service"
                closeTimeout="01:50:00"
                openTimeout="01:50:00" receiveTimeout="01:50:00" sendTimeout="01:50:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                maxReceivedMessageSize="2147483647" messageEncoding="Text"
                textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name = "Customer_Service"  behaviorConfiguration="returnFaults">
            <endpoint name="NAVBinding_ICustomer_Service"
               address  = "http://localhost:8000/nav/customer"
               binding  = "basicHttpBinding"
               bindingConfiguration= "NAVBinding_ICustomer_Service"
               contract = "NAVServiceReference.ICustomer_Service"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="returnFaults" >
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 </system.serviceModel>

Отредактировано (добавлено):

Каков правильный и лучший способ превратить службу WCF из «черного ящика» в службу, которая легко устраняется, что объясняет причину, по которой что-то идет не так, как ожидалось? Какие инструменты, методы вы используете для устранения неполадок службы WCF?

Ответы [ 6 ]

26 голосов
/ 29 декабря 2009

Игнорирование проблем с maxRequestLength (на которые ответили другие), Я постараюсь ответить на ваш оригинальный вопрос о том, как устранить неполадки в WCF.

Если вы уже используете Service Trace Viewer (я не могу сказать по вопросу если вы просто просматривали их вручную), возможно, что не все детали вдаваясь в файл.

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

 <system.serviceModel>
  <diagnostics>
   <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="-1" />
  </diagnostics>
 </system.serviceModel>

Если вы не используете Microsoft Service Trace Viewer, я рекомендую это сделать. Это дает всю необходимую информацию, чтобы отследить эти хитрые сообщения рукопожатие, сообщение исключения размера и т. д. Вот справочник MSDN, чтобы вы начали http://msdn.microsoft.com/en-us/library/aa751795.aspx

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

Troubleshooting Using the Service Trace Viewer

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

7 голосов
/ 15 сентября 2010

Последние два с лишним дня я пытался выяснить, почему я получаю «Базовое соединение было закрыто: соединение было неожиданно закрыто» с возвращением вызова метода с большим количеством данных по сравнению с тем, когда данных не так много (т. Е. это работает нормально с меньшими наборами данных, возвращаемых только).

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

Посмотрев на исключение и цепочку, я увидел следующий корень, ошибка: «Существующее соединение было принудительно закрыто удаленным хостом» - это было System.Net.Sockets.SocketException

Тогда вверх по цепочке вызовов было: «Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом». - исключение System.IO.IOException, затем

«Базовое соединение было закрыто: при получении произошла непредвиденная ошибка». - исключение System.Net.WebException, а затем, наконец, то, что было сообщением о перехваченном исключении,

"Произошла ошибка при получении ответа HTTP. Это может быть связано с тем, что привязка конечной точки службы не использует протокол HTTP. Это также может быть связано с тем, что сервер прерывает контекст запроса HTTP (возможно, из-за службы выключение). См. журналы сервера для более подробной информации. " - исключение System.ServiceModel.CommunicationException

Включение трассировки, а затем просмотр журналов трассировки с помощью TraceViewer действительно облегчило это наблюдение, но никогда не указывало мне истинную причину моей ошибки «Существующее соединение было принудительно закрыто удаленным хостом».

В моем случае моя служба WCF размещается на IIS6, и только когда я связался с нашей институциональной поддержкой, отвечающей за эти серверы, и попросил их просмотреть в журналах системных событий, я сразу увидел ответ - исключение System.OutOfMemoryException!

Моя служба WCF работает в выделенном 200 МБ ОЗУ, и мой метод потреблял больше, чем этот. Я посмотрел в своем методе и в конце концов нашел блок кода, который должен был быть вне / ниже блока (цикла), в котором он находился. ..so в моем методе был создан экспоненциальный тип коллекции.

Надеюсь, что это может помочь другим.

2 голосов
/ 29 декабря 2009

Чтобы ответить на ваш вопрос о том, как создать сервис WCF, который можно легко устранить. Один из способов - свести к минимуму количество потенциальных ошибок, чтобы при поиске и устранении неисправностей было меньше вещей.

Существует два основных источника ошибок:

  • Ошибка из-за конфигурации
  • Исключение, выданное службой WCF

Ошибки в конфигурации часто происходят из-за несоответствия между клиентом и службой. Чтобы избежать этого, поместите все возможные конфигурации в BindingConfiguration, скопируйте и используйте их как на клиенте, так и на сервере. Я думаю, что именно в этом и заключается ваша проблема, вы обновляете сервис web.config, добавляя вещи, которые также должны быть в конфигурации клиента. Например, максимальный размер или буферизация в одном, а в потоке - в другом.

Ошибки, генерируемые службой, должны быть выброшены как FaultException и определены в Контракте как FaultContract .

Для оставшихся ошибок вам нужно посмотреть файл trace.svclog, как описано в других постах. Вам также необходимо просмотреть журнал событий и журнал IIS, вызовы могут быть заблокированы до того, как они достигнут службы WCF.

1 голос
/ 24 сентября 2013

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

Напомним: во-первых, я получил страшную ошибку Not Found, используя WCF из службы Silverlight.Нет, это не потому, что сервис не найден.Мне удалось пройти через вызываемый метод обслуживания до конца, включая возврат.Затем клиентская сторона получила исключение в асинхронной конечной части вызова.Нет объяснения.Это не имеет никакого отношения к привязкам и т. Д.

Затем я нашел подобные сообщения на форуме об использовании средства просмотра трассировки.Оказывается, я уже настроил это, но не получил никакого следа (таким образом, я полагал, что мой сервис должен быть в порядке, особенно, так как я мог проследить через).Неправильный мальчик Бонго.Затем я обнаружил другое сообщение о том, что малоизвестный факт: если вы настроили прослушиватель трассировки для записи в «C: \ logs \ mylog», вы ДОЛЖНЫ сначала создать C: \ logs вручную.Это не сделает это для вас.

Хорошо, теперь я получаю журнал и поднимаю его в TraceViewer.После чего я получаю «сообщение об ошибке» о неопределенной строке.Тридцать минут спустя я нахожу другое сообщение о том, что все знают, что сначала вы должны завершить работу локального сервера разработки, чтобы удалить последние сообщения.Вы знаете, те, которые на самом деле говорят вам, что пошло не так?

Теперь я перехожу к реальным ошибкам и смотрю на каждую из них: выбрасываю исключение, RequestContext прерван и сообщение с ошибкой для отправки ответа по http.Только первое имеет значение.За исключением, конечно, взгляда на нижнюю панель, он не дал мне никакой полезной информации, кроме как сказать, что была ошибка Сериализации.Хм, "где" было бы неплохо.

В конце концов я внезапно заметил, что есть небольшая вкладка XML в нижней панели, прямо рядом с вкладкой "Форматированный".Когда я нажимаю на это, для моего сообщения ThrowingAnException, это - огромный дамп с очень специфическим сообщением, которое привело меня прямо к проблеме:

System.ServiceModel.CommunicationException, System.ServiceModel, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089 Произошла ошибка при попытке сериализации параметра: GetTimecardsWithAlertsResult.Сообщение InnerException "Enum value" 0 "недопустимо для типа" Timeclock.Web.ShiftManager.AlertType "и не может быть сериализовано.Убедитесь, что необходимые значения перечисления присутствуют и помечены атрибутом EnumMemberAttribute, если тип имеет атрибут DataContractAttribute. '.Пожалуйста, смотрите InnerException для получения более подробной информации.

Проблема была в том, что я не инициализировал основанный на перечислении член класса, поэтому это был 0, что НЕ было одним из моих допустимых значений перечисления.Очень просто исправить.

И, разумеется, Microsoft очень просто это обнаруживать, учитывая тот большой объем информации, который они успешно прятали от посторонних глаз в течение 3 часов.

Вот идея Microsoft - как насчет того, чтобы предложить способ уловить эти ошибки и все важные сообщения об исключениях на сервере?Или позволить им полностью перейти к клиенту Silverlight?Вы знаете, чтобы было легче увидеть, что происходит, поэтому я мог бы решить эту простую проблему за 3 секунды, которых она заслуживает, вместо 3 часов, которые я должен взимать с моего клиента за то, что он ничего не делал?

О, Я знаю.Это действительно сложно, потому что это асинхронный вызов по протоколу http, а злой старый интернет делает его вредным для вашего мозга.Но угадайте что?Вы Microsoft.У вас есть неограниченное время и деньги.И вы влияете на миллионы людей.Когда вы облажаетесь с этим видом **, как вы делаете с тысячами сценариев, в которых вас просто не волнуют, вы затрагиваете сотни тысяч разработчиков по всей планете.

Оглянись на StackOverflow. Посмотрите, сколько людей по всему миру, умных людей, пытающихся написать программное обеспечение для выполнения полезных важных дел, просто не погружены в невероятные мелочи, подобные описанным выше, потому что, вы знаете, у них есть реальная работа.

Умножьте мои 3 часа на эту дурацкую проблему раз десятки тысяч разработчиков раз 30-40 эпизодов такого рода дерьма в типичном году, и вы увидите, какие катастрофы вы вызываете. Можно сказать «вот почему нам платят большие деньги», но подумайте о том, какую действительно хорошую работу мы все могли бы выполнить в мире, если каждый раз, когда мы оборачиваемся, нам не нужно погружаться на 3 часа * * яму вырыли для нас?

Microsoft, ты плохой для программирования, плохой для бизнеса и плохой для человечества. Мне все равно, сколько компьютеров работает с вашим программным обеспечением. Вам нужно сделать лучше. Пожалуйста, начните вести себя так, как будто вы понимаете, насколько сильно вы оскорбляете миньонов трудолюбивых людей в мире, в каждой стране, каждый день. И насколько лучше было бы сделать это место, если бы ты просто действовал так, как это важно, чтобы все делать правильно.

Тим Джонсон

1 голос
/ 20 декабря 2009

Попробуйте установить свойство maxRequestLength :

<system.web>
    <httpRuntime maxRequestLength="2147483647" />
</system.web>
0 голосов
/ 19 декабря 2009

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

Попробуйте это:

  1. В файле конфигурации на стороне сервера установите includeExceptionDetailInFaults = "true"
  2. Когда вы используете клиентскую сторону, не используйте шаблон использования. Проверьте эту статью.

Я не думаю, что вам нужно отслеживать. Попробуйте описанное выше, и вы сможете увидеть точную ошибку связи.

О, и кстати, ваш клиент приложение Silverlight? Если так, то это немного сложнее ... Ознакомьтесь с этой статьей.

...