Подписчик темы служебной шины Azure получает заказ

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

Но на самом деле все немного иначе, по моему сценарию

  • Ввод осуществляется примерно через каждые две секунды (временная метка верна, я ее проверил)
  • Если я на какое-то время отключу приемник, сообщения начнут выстраиваться в очередь в Azure по подписке.
  • Затем, если я снова подключу приемник, код приема будет получать сообщения довольно быстро, но порядок не сохраняется?
  • Однако, если я держу клиента подключенным, сообщения принимаются по порядку (1 сообщение через две секунды)

Получение кода

SubscriptionClient Client = SubscriptionClient.CreateFromConnectionString(connectionString, topicname, subscription_name);

                // Configure the callback options.
                OnMessageOptions options = new OnMessageOptions();
                options.AutoComplete = false;
                options.AutoRenewTimeout = TimeSpan.FromMinutes(1);

                // Callback to handle received messages.
                Client.OnMessage((message) =>
                {
                    try
                    {
                        // Process message from queue.
                        string payload = message.GetBody<string>();
                        var myData = JsonConvert.DeserializeObject<MyData>(payload);
                        if(myData != null)
                        {

                            //Timestamp is not in order, when I connect after few minutes
                            Debug.WriteLine("SBC ==> " + myData.Timestamp);

                        }
                        // Remove message from queue.
                        message.Complete();
                    }
                    catch (Exception)
                    {
                        // Indicates a problem, unlock message in queue.
                        message.Abandon();
                    }
                }, options);

Вывод

SBC ==> 5/23/2017 1:06:43 PM
SBC ==> 5/23/2017 1:06:45 PM
SBC ==> 5/23/2017 1:07:23 PM
SBC ==> 5/23/2017 1:07:19 PM
SBC ==> 5/23/2017 1:07:27 PM
SBC ==> 5/23/2017 1:07:07 PM
SBC ==> 5/23/2017 1:06:49 PM
SBC ==> 5/23/2017 1:07:47 PM
SBC ==> 5/23/2017 1:06:47 PM
SBC ==> 5/23/2017 1:08:03 PM
SBC ==> 5/23/2017 1:06:55 PM
SBC ==> 5/23/2017 1:06:51 PM
SBC ==> 5/23/2017 1:07:03 PM
SBC ==> 5/23/2017 1:07:51 PM
SBC ==> 5/23/2017 1:06:57 PM
SBC ==> 5/23/2017 1:07:05 PM
SBC ==> 5/23/2017 1:07:39 PM
SBC ==> 5/23/2017 1:07:43 PM
SBC ==> 5/23/2017 1:06:59 PM
SBC ==> 5/23/2017 1:07:09 PM
SBC ==> 5/23/2017 1:06:53 PM
SBC ==> 5/23/2017 1:07:33 PM
SBC ==> 5/23/2017 1:07:25 PM
SBC ==> 5/23/2017 1:07:57 PM
SBC ==> 5/23/2017 1:08:13 PM

Кто-нибудь может объяснить, почему это так? Меня это немного сбивает с толку?


person Muhammad Ummar    schedule 23.05.2017    source источник


Ответы (2)


Хотя сервисная шина Azure предлагает себя как FIFO (First in First Out), это действительно работает только во время непрерывного сеанса. Как вы испытали:

Однако, если я оставлю клиента подключенным, сообщения будут поступать по порядку.

Чтобы обойти это, вы можете использовать другой режим. Взгляните на режимы ReceiveAndDelete и PeekLock по ссылке ниже.

Документы служебной шины

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

Как выполнить FIFO с помощью тем о служебной шине Azure

Как гарантировать FIFO очереди Azure

РЕДАКТИРОВАТЬ

Эта ссылка содержит некоторые сведения о ФИФО

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

Гарантированный шаблон FIFO в очередях служебной шины требует использования сеансов обмена сообщениями. В случае сбоя приложения при обработке сообщения, полученного в режиме Peek & Lock, в следующий раз, когда получатель очереди примет сеанс обмена сообщениями, он начнет с ошибочного сообщения по истечении периода времени жизни (TTL).

Кажется, что в документах довольно не хватает реализации сеансов сообщений, но, насколько я понимаю, это из класса MessageSession, и это AcceptMessageSessionmethod

person NPhillips    schedule 23.05.2017
comment
Спасибо за комментарии. Не могли бы вы обратиться к какой-либо документации на MSDN, где описывается этот The problem you are having is that when you disconnect the receiver the messages that time out begin to retry after a set amount of time. This causes them to lose the order they were sent in.? Было бы действительно полезно. - person Muhammad Ummar; 23.05.2017
comment
Добавлю к ответу. - person NPhillips; 23.05.2017
comment
Я удалил цитируемую вами часть из вопроса, так как не могу предоставить для нее надежный источник. У меня была эта проблема некоторое время назад, и это было моим пониманием проблемы, но, конечно, мое слово мало что значит без документов, подтверждающих это. Вы можете найти этот пост в блоге полезным, хотя я подозреваю, что он немного устарел: ben-morris.com/ - person NPhillips; 23.05.2017

Как и сказал @NPhillips, вам нужно использовать функцию сеансов сообщений ASB для достижения поведения FIFO. Это означает несколько вещей, на которые важно обратить внимание:

  1. Получатель будет обрабатывать только один сеанс за раз
  2. Параллельная обработка невозможна, вы получите одно сообщение за то время, которое потребуется для обработки.
  3. Отправителю необходимо присвоить каждому сообщению идентификатор сеанса.

Лучшим примером и объяснением будет тот, который был опубликован командой ASB на GitHub здесь.

person Sean Feldman    schedule 23.05.2017