.NET — Служебная шина — Перемещение сообщения в DLQ

Я использую служебную шину Azure с библиотекой Mass Transit в приложении .NET WebApi. У меня есть ServiceA, где я публикую свое сообщение StartProccess. Это сообщение также используется в конечном автомате — StartStateMachine.

Это сообщение отправляется в ServiceB (это функции Azure), где оно обрабатывается и отправляется. Я вынужден зарегистрировать потребителя для ServiceB в ServiceA, используя следующую запись, поскольку, судя по тому, что я нашел и прочитал, подписка должна уже существовать для функций Azure. Обычно я бы выполнил эту регистрацию с помощью MassTransit, но MassTransit не может создать потребителя без «привязки» — реализации потребителя. Это связано с тем, что потребитель находится в другом проекте/сервисе.

if (!(await adminClient.TopicExistsAsync(formatter.MessageName<StartProccess>()));
    adminClient.CreateTopicAsync(formatter.MessageName<StartProccess>());
    
if (!(await adminClient.SubscriptionExistsAsync(formatter.MessageName<StartProccess>()), formatterCheckFunc.ConsumerFromMessageName<StartProccess>()).Value)
    await adminClient.CreateSubscriptionAsync(new CreateSubscriptionOptions(formatter.MessageName<StartProccess>(), formatterCheckFunc.ConsumerFromMessageName<StartProccess>()) { MaxDeliveryCount = 1 });

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

Все работает так, как должно. Однако время от времени и очень редко, например, 1 раз из 100, я получаю сообщение StartProccess, которое попадает в DLQ с сообщением - превышено максимальное количество отправок. Я не понимаю, почему. Это действительно устанавливает его время от времени. Таким образом, моя государственная машина не запускается и работает очень неуклюже.

Кто-нибудь сталкивался с этой проблемой? Спасибо

Редактировать:

Обработка сообщений

    try
    {
        await _receiver.HandleConsumer<Consumer>(TopicName, SubscriptionName, message, cancellationToken);
        await messageActions.CompleteMessageAsync(message);
    }
    catch (SomeException ex)
    {
        await messageActions.AbandonMessageAsync(message);
        _log.LogWarning("LogIt");
    }
    catch
    {
        // This?
        await messageActions.CompleteMessageAsync(message);
        // Or this?
        await messageActions.DeadLetterMessageAsync(message);
        throw;
    }
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Все работает так, как должно. Однако время от времени и очень редко, например, 1 раз из 100, я получаю сообщение StartProccess, которое попадает в DLQ с сообщением - превышено максимальное количество отправок.

Причиной этого является установка MaxDeliveryCount на 1.

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

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

Petr Klekner 30.04.2024 07:57

Это не неловко — так задумано. Обработка сообщения может завершиться неудачно по разным причинам. Функция может быть прекращена, связь с брокером ASB может прерваться и т. д. Если вы установите MaxDeliveryCount на 1, в DLQ будут время от времени появляться сообщения. Вы предполагаете, что исключение возникнет только в том случае, если в сообщении есть логическая ошибка. Но это не так.

Sean Feldman 30.04.2024 08:17

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

Petr Klekner 30.04.2024 08:49

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

Sean Feldman 30.04.2024 15:51

Если при вызове функции Azure есть исключение, я не хочу его повторять. Я хочу повторить попытку только в том случае, если я явно укажу (список исключений), когда хочу разрешить повторную попытку. Но я полагаю, что мне придется реализовать эту логику самому. Я отредактировал вопрос и добавил образец. Создание исключения гарантирует, что будет вызвана очередь ошибок, и поэтому я узнаю об этом. Лучше переместить сообщение в dlq или пометить как завершенное?

Petr Klekner 02.05.2024 08:29

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

Sean Feldman 02.05.2024 16:35

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