Rebus Azure ServiceBus - отсутствует MessageID для сообщения, полученного от внешней службы

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

Я получаю сообщение об ошибке:

Получено сообщение с пустым или отсутствующим заголовком 'rbs2-msg-id'!

Я просмотрел GitHub и заметил этот список о том, что у кого-то была похожая проблема с RabbitMQ, и было рекомендовано использовать декоратор:

https://github.com/rebus-org/Rebus/issues/508

Однако я не уверен, как это сделать только для идентификатора сообщения.

Одним из вариантов, который я выбрал, было изменение кода Rebus.AzureTransport для этого:

var messageId = headers.GetValueOrNull(Headers.MessageId);

if (string.IsNullOrEmpty(messageId))
{
    messageId = Guid.NewGuid().ToString();
    headers[Headers.MessageId] = messageId;
}

Но предпочел бы альтернативу!

Еще одна вещь, которую я заметил, это то, что BrokeredMessage помещается на ASB следующим образом:

var message = new BrokeredMessage("<xml>This is a test message: " + DateTime.Now+ "</xml>");

Он не сериализуется правильно, когда его получает Rebus. Я получаю следующую ошибку:

Необработанное исключение 1 при обработке сообщения с идентификатором db13880d-124c-4ed5-993e-96faeca0f140: System.Collections.Generic.KeyNotFoundException: Не удалось найти ключ 'rbs2-content-type'

При переопределении Сериализатора, нижележащее сообщение выглядит так:

@ strin3http: //schemas.microsoft.com/2003/10/Serialization/? 6Это тестовое сообщение: 12.06.2016, 07:44:21

поэтому я не уверен, что я делаю неправильно.

Заранее спасибо.

1 ответ

Ну... как говорится в сообщениях об ошибках, входящее сообщение не содержит достаточной информации для того, чтобы Ребус его обработал.

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

На вашем месте я бы, вероятно, не использовал бы Rebus для получения сообщений из очереди, которая не содержит сообщений, отправленных Rebus. Или я мог бы сделать это - но только если входящие сообщения было очень легко адаптировать для соответствия формату Rebus.

Однако это может быть немного громоздким, потому что - как вы правильно заметили - для этого требуется наличие определенных заголовков, которые действуют как подсказки для Rebus о том, как отслеживать его между попытками обработки, как десериализовать его, где ответить на если bus.Reply называется и т. д. Так что я все равно мог бы в конечном итоге не делать этого:)

Я предлагаю вам сделать что-то вроде этого:

while(true)
{
    var message = GetNextMessageOrNullFromQueue();

    if (message == null) continue;

    UnwrapMessageAndSendWithRebusToRebusQueue(message);
}

Таким образом, вы можете кодировать свой собственный цикл приема для получения ваших отформатированных сообщений Azure Service Bus, делегируя фактическую обработку (возможно, также десериализацию из текста XML в объекты?) конечной точке Rebus.

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

Другие вопросы по тегам