Прослушиватель очереди шины хранения Azure, записанный как COM-элемент управления, работающий как служба, перестает получать, пока пользователь не войдет на сервер

#.net #azure #service #servicebus #clarion

#.net #azure #Обслуживание #servicebus #clarion

Вопрос:

Я написал сборку для получения сообщений из очереди шины хранения Azure. Эта сборка записана как COM-элемент управления без регистрации. Он используется в службе Windows, написанной на языке Clarion для Windows. Windows Server 2016. Майкрософт.Azure.Версия ServiceBus: 4.1.4.0 .Net версии 4.7.2

Служба успешно получает сообщения в течение определенного периода времени, а затем перестает получать новые сообщения. Эта служба также является веб-сервером, и я могу успешно перейти на сервер, когда он не получает сообщения шины хранения, поэтому я знаю, что служба все еще работает. Что действительно странно, так это то, что если я подключаюсь к удаленному рабочему столу на сервере Windows, служба сообщений внезапно снова начинает читать сообщения. Я ничего не делаю со службой. Только мой вход на сервер приводит к получению сообщений. Служба работает под учетной записью домена, которая отличается от учетной записи, которую я использую для удаленного доступа к серверу. У меня также была служба, работающая в локальной системе.

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

Код службы довольно прост:

        public void Initialize(string pServiceBusConnection, string pQueueName)
        {
            try
            {
                WriteLog($"Initialize: "   pQueueName);
                ServiceBusConnectionString = pServiceBusConnection;
                QueueName = pQueueName;
                queueClient = new QueueClient(ServiceBusConnectionString, QueueName);
                RegisterOnMessageHandlerAndReceiveMessages();
            }
            catch (Exception e)
            {
                WriteLog(e.GetType().Name   " : "   e.Message);
            }

        }
        private void RegisterOnMessageHandlerAndReceiveMessages()
        {
            var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
            {
                MaxConcurrentCalls = 1,
                AutoComplete = false
            };

            WriteLog($"Register the function that will process messages");

            queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
        }

        private async Task ProcessMessagesAsync(Microsoft.Azure.ServiceBus.Message pMessage, CancellationToken pToken)
        {
            WriteLog($"ProcessMessagesAsync");
            //Save off message details and send event back to window saying new data is available.
            MsgReceived = JsonConvert.DeserializeObject<ReceiveStatusUpdate>(Encoding.UTF8.GetString(pMessage.Body));
            WriteLog($"Received message: SequenceNumber:{pMessage.SystemProperties.SequenceNumber} Body:{MsgReceived.LoanNumber}");
            LoanNumber.Text = MsgReceived.LoanNumber;
            SigningStatus.Text = MsgReceived.SigningStatus;
            LocationId.Text = MsgReceived.LocationId.ToString();
            try
            {
                Invoke((Action)(() => MessageReceived(Encoding.UTF8.GetString(pMessage.Body))));
            }
            catch (Exception e)
            {
                WriteLog(e.GetType().Name   " : "   e.Message);
            }

            await queueClient.CompleteAsync(pMessage.SystemProperties.LockToken);

        }

        private Task ExceptionReceivedHandler(ExceptionReceivedEventArgs arg)
        {
            WriteLog(arg.Exception.GetType()   ":"   arg.Exception.Message);
            throw arg.Exception;
        }

  

Сообщения об ошибках или исключения не регистрируются.
Кто-нибудь знает, что может произойти, из-за чего сообщения перестают приниматься?
Я рассматриваю возможность периодической остановки потока прослушивания и его перезапуска. Тот факт, что удаленное подключение к серверу влияет на службу прослушивания, очень сбивает с толку.

У меня есть дополнительная информация, которую можно добавить к этой проблеме.
Во-первых, я обновил сборки служебной шины Azure до последней версии 5.0. Во-вторых, я полностью переписал службу на C # .Net исключает Clarion из уравнения. Ошибки по-прежнему возникают с новой службой и по-прежнему устраняются при удаленном подключении к серверу и входе в систему. Это генерируемое исключение.

Майкрософт.Azure.ServiceBus.Исключение ServiceBusCommunicationException : существующее соединение было принудительно закрыто удаленным хостом ErrorCode: ConnectionReset

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

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

Комментарии:

1. Прошло много времени с тех пор, как я слышал ссылку на Clarion. Учитывая его возраст, я подозреваю, что его использование в службе Windows может быть немного взломано, возможно, в зависимости от скрытых окон и перекачки сообщений (как и COM в STA): может ли вход в систему вызывать какую-то зависимость от GUI? Также я вижу, что вы используете асинхронность: Clarion предшествовал потоковой передаче в Windows, так что это может быть проблемой. Предложил бы либо удаленную отладку, либо гораздо больше диагностики…

2. Спасибо, Ричард. У меня есть десятки сервисов, которые я написал в Clarion, которые успешно работают и знают о 100. Само по себе, я думаю, говорить, что реализация сервиса, вероятно, является взломом, несправедливо. Clarion имеет полную поддержку упреждающей потоковой обработки. Интерфейс к прослушивателю выполняется в собственном потоке. Есть ли у вас предложение по методике выполнения «гораздо большей диагностики»?

3. «Немного больше диагностики»: добавляйте больше, пока не отследите все. «Немного взлома»: думая, что Clarion может использовать тот же подход, что и VB6: он работал в основном (и работал со многими службами, которые успешно работали), но это не была полная интеграция.