Как получить указанное сообщение из раздела служебной шины Azure, а затем удалить его из раздела?

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

   static async Task ProcessMessagesAsync(Message message, CancellationToken token)
    {
        // Process the message.
        Console.WriteLine($"Received message: WorkOrderNumber:{message.MessageId} SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
        Console.WriteLine("Enter the WorkOrder Number you want to delete:");
        string WorkOrderNubmer = Console.ReadLine();
        if (message.MessageId == WorkOrderNubmer)
        {
            //TODO:Post message into other topic(Priority) then delete from this current topic.
            var status=await SendMessageToBus(message);
            if (status == true)
            {
                await normalSubscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
                Console.WriteLine($"Successfully deleted your message from Topic:{NormalTopicName}-WorkOrderNumber:" + message.MessageId);
            }
            else
            {
                Console.WriteLine($"Failed to send message to PriorityTopic:{PriorityTopicName}-WorkOrderNumber:" + message.MessageId);
            }

        }
        else
        {
            Console.WriteLine($"Failed to delete your message from Topic:{NormalTopicName}-WorkOrderNumber:" + WorkOrderNubmer);
            // Complete the message so that it is not received again.
            // This can be done only if the subscriptionClient is created in ReceiveMode.PeekLock mode (which is the default).
            await normalSubscriptionClient.CompleteAsync(message.SystemProperties.LockToken);

            // Note: Use the cancellationToken passed as necessary to determine if the subscriptionClient has already been closed.
            // If subscriptionClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
            // to avoid unnecessary exceptions.
        }

    }

Моя проблема с этим подходом:

  1. Он не масштабируется; а если сообщение 50-е в коллекции? Нам нужно будет выполнить итерацию 49 раз и пометить как удаленные.

  2. Это длительный процесс.

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

Итак, может ли кто-нибудь подсказать мне, как решить эту проблему?


person Pradeep    schedule 07.06.2019    source источник
comment
Я собирался ответить, но потом понял, что ваш бизнес-кейс совсем непонятен. Помимо технической части, которая кажется несогласованной, что вы на самом деле пытаетесь реализовать? Какую бизнес-проблему вы решаете? Не могли бы вы описать это без Azure Service Bus, разделов, порядковых номеров? Поступая так, вы останетесь в стороне от решения и поможете понять, какие варианты могут быть.   -  person Sean Feldman    schedule 07.06.2019
comment
@SeanFeldman, я хочу получить конкретное сообщение из раздела служебной шины Azure без логики итераций, а затем удалить его из раздела.   -  person Pradeep    schedule 10.06.2019
comment
Я понимаю эту часть. Но зачем вам это делать? Какую проблему вы решаете?   -  person Sean Feldman    schedule 10.06.2019
comment
@SeanFeldman, мне нужно обрабатывать сообщения на основе уровня приоритета. Но иногда я решаю, что сообщение имеет высокий приоритет после отправки в тему с обычным приоритетом. Итак, сначала я заблокировал это сообщение, отправил его в приоритетную тему, а затем удалил его из темы с обычным приоритетом.   -  person Pradeep    schedule 11.06.2019
comment
Вы не можете удалить сообщение из темы, только из очередей и подписок. Следовательно, код для удаления сообщений должен быть на стороне потребителей подписки. Кроме того, если вы обработали сообщение, его приоритет должен быть повышен, завершите использованное сообщение и отправьте другое с более высоким приоритетом. Не нужно удалять его из архива. Это все равно не поможет, если у вас несколько подписчиков.   -  person Sean Feldman    schedule 11.06.2019


Ответы (1)


Итак, если я правильно понимаю ваши вопросы и комментарии, вы пытаетесь сделать что-то вроде этого:

  1. Входящие сообщения относятся либо к стандартной теме, либо к приоритетной теме.
  2. Некоторые процессы проверяют сообщения в стандартной теме и «перемещают» их в приоритетную тему на основе некоторых критериев, удаляя их из стандартной темы и добавляя их в приоритетную тему.
  3. Сообщения обрабатываются в обычном режиме.

введите здесь описание изображения

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

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

Вот как будет работать этот процесс:

  1. Входящие сообщения добавляются в очередь сортировки. Обратите внимание, что это отдельная очередь, а не тема. На этом этапе процесса мы хотим убедиться, что существует только одна копия каждого сообщения.
  2. Процесс сортировки перемещает сообщения из очереди сортировки в стандартную или приоритетную очередь, в зависимости от ситуации. Используя что-то вроде функций Azure, вы можете довольно легко масштабировать этот процесс.
  3. Сообщения из тем обрабатываются в обычном режиме.

введите здесь описание изображения

person SamaraSoucy    schedule 17.06.2019