Почему мой канал WCF выходит из строя? - PullRequest
3 голосов
/ 18 августа 2010

У меня есть компьютер, на котором запущена одна программа, которая управляет до 48 отдельными процессами на 4 других компьютерах.У меня службы WCF (по одной для каждого процесса), настроенные так:

    public void StartService(Uri uri, string identifier)
    {
        unitMetaData = identifier;
        var binding = new WSDualHttpBinding(WSDualHttpSecurityMode.None);
        binding.ReliableSession.InactivityTimeout = TimeSpan.FromDays(20);
        var reader = binding.ReaderQuotas as XmlDictionaryReaderQuotas;
        reader.MaxStringContentLength = WCFContentSize; // 16777216
        service = new ServiceHost(this, uri);
        service.Faulted += TestService_Faulted;
        service.AddServiceEndpoint(
            typeof(IController),
            binding,
            identifier);
        service.Open();
    }

Вот код для удаленных процессов:

    public void Connect()
    {
        // External binding used to change the WCF XML text content size
        var binding = new WSDualHttpBinding(WSDualHttpSecurityMode.None);
        binding.ReliableSession.InactivityTimeout = TimeSpan.FromDays(20);
        var reader = binding.ReaderQuotas as XmlDictionaryReaderQuotas;
        reader.MaxStringContentLength = WCFContentSize; // 16777216
        DuplexChannelFactory<IController> factory = new DuplexChannelFactory<IController>(new InstanceContext(this), binding);
        controllerChannel = factory.CreateChannel(new EndpointAddress(controllerAddress, new DnsEndpointIdentity(controllerAddress.DnsSafeHost), new System.ServiceModel.Channels.AddressHeaderCollection()));
        ((IClientChannel)controllerChannel).OperationTimeout = TimeSpan.FromSeconds(ChannelOperationTimeoutInSeconds); // 300
        controllerChannel.RequestTestData();
    }

У меня есть код, который будетудаленная функция «Ping ()», которая просто возвращает строку «Pong» примерно каждые 30 секунд в каждом удаленном процессе.Я сделал это, чтобы убедиться, что соединение остается открытым, поскольку у меня возникли проблемы с тайм-аутом ReliableSession.Иногда (как это происходит слишком часто для производственного кода) я получаю следующее исключение от одной и обычно нескольких служб, к которым подключаются процессы тестирования:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServerReliableDuplexSessionChannel, cannot be used for communication because it is in the Faulted state.

Server stack trace: 
   at System.ServiceModel.Channels.TransmissionStrategy.WaitQueueAdder.Wait(TimeSpan timeout)
   at System.ServiceModel.Channels.TransmissionStrategy.InternalAdd(Message message, Boolean isLast, TimeSpan timeout, Object state, MessageAttemptInfo& attemptInfo)
   at System.ServiceModel.Channels.ReliableOutputConnection.InternalAddMessage(Message message, TimeSpan timeout, Object state, Boolean isLast)
   at System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.DuplexChannel.Send(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   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)
   at SEL.MfgTestDev.ESS.ServiceContracts.ITestProcessClient.Ping()
   at SEL.MfgTestDev.ESS.Testing.Service.TestService.Ping() in C:\Projects\Mfg_TestDev_ESS_Rev3\branches\MSU-5-18-2010\ESS.Testing.Service\TestService.cs:line 349

Так что же происходит?Почему это внезапно заканчивается в неисправном состоянии.Есть ли способ узнать причину сбоя соединения?

Ответы [ 3 ]

9 голосов
/ 18 августа 2010

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

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

Edit:

Описание проблемы недостаточно. Также архитектура очень странная. Существует не одна услуга, связывающаяся с 48 клиентами по дуплексным каналам, но 48 таких же служб, связывающаяся с одним 1 клиентом по дуплексным каналам. Это, конечно, может добавить дополнительные проблемы, которые не известны из обычных сценариев, поэтому диагностика (отслеживание / счетчики производительности) действительно необходима!

При проверке кода метода Connect даже кажется, что обратный вызов клиента является одноэтапным взаимодействием со всеми 48 службами, не так ли? Какой режим параллелизма используется для этого обратного вызова? Если режим параллелизма один, могут возникнуть проблемы с тайм-аутом при вызове обратного вызова, так как размер сообщения установлен в 16 МБ. Если все 48 процессов одновременно отправляют сообщение размером 16 МБ, они будут поставлены в очередь и обработаны в порядке FIFO. Настройки по умолчанию требуют обработки в течение 30 секунд, в противном случае возникает исключение тайм-аута и сбой канала. Если режим параллелизма является многократным, в реализации обратного вызова все еще могут быть проблемы с синхронизацией.

2 голосов
/ 23 августа 2010

Ваш канал может быть в неисправном состоянии, если вы не переводите исключения службы в FaultException или FaultException<T>:

http://blogs.msdn.com/b/pedram/archive/2008/01/25/wcf-error-handling-and-some-best-practices.aspx

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

0 голосов
/ 18 августа 2010

Предполагая, что вы используете тот же канал для проверки связи с удаленной службой, что и другие удаленные вызовы (в чем и заключался весь смысл этого запроса?), Возможно, один из других вызовов метода исключен / истек или истек срок его действия.channel?

Кроме того, в вашей конфигурации для ServiceBehaviors для 'includeExceptionDetailInFaults' установлено значение true?например,

<behaviors>
   <behavior name="MyServiceBehaviors">
      <serviceDebug includeExceptionDetailInFaults="true" />
   </behavior>
</behaviors>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...