Обработка исключений в аксоне при многократном прослушивании одного и того же события в одном приложении весенней загрузки - PullRequest
2 голосов
/ 22 апреля 2020

Мы находимся в процессе интеграции аксона в наше существующее приложение с пружинной загрузкой. В настоящее время мы используем Axon 4.1.2 и Axon Server.

Например, в процессе регистрации мы запускаем RegisterCommand, который читается RegisterAggregate и который запускает RegistrationDoneEvent. * 1006. *

Есть два EventHandlers слушающих это RegistrationDoneEvent. Это RegistrationNeo4jEventHandler и RegistrationSqlEventHandler.

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

Как мы можем сделать так, чтобы SqlEventHandler завершал и фиксировал, НО Neo4JEventHandler повторов?

Во-вторых, как нам полностью прекратить повторную попытку события в случае сбоя ? Допустим, у нас было четыре обработчика событий (HandlerA, HandlerB, Handler C, HandlerD), которые прослушивали событие SAME . Если обработчик C завершается неудачно, мы хотим, чтобы он был повторен, когда мы допустим исправление основной проблемы, НО также убедитесь, что другие обработчики, которые прослушали событие SAME , не были перезапущены.

Следующие фрагменты кода включают агрегат и обработчики событий.

RegisterAggregate

@Aggregate
public class RegisterAggregate {

    ....

    @CommandHandler
    public RegisterAggregate(RegisterCommand command) {
        apply(new RegistrationDoneEvent(command));
    }
}

RegistrationSqlEventHandler

@Service
@Transactional
public class RegistrationSqlEventHandler { 

    @EventHandler
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public void on(RegistrationDoneEvent event) {
        ....
    }
}

РегистрацияNeo4jEventHandler

@Service
@Transactional
public class RegistrationNeo4jEventHandler { 

    @EventHandler
    public void on(RegistrationDoneEvent event) {
        ....
    }
}

1 Ответ

2 голосов
/ 24 апреля 2020

Я разделю мой ответ на два, так как вы задали не один, а два вопроса. Во-первых, давайте поговорим об этом вашем вопросе:

Как мы можем сделать так, чтобы RegistrationSqlEventHandler завершил и передал, НО RegistrationNeo4jEventHandler повторов?

От Наименование уже очевидно: оба компонента обработки событий (т. е. класс you write, содержащий @EventHandler аннотированные методы) служат совершенно другой модели запросов. Первая направлена ​​на СУРБД, а вторая служит для обновления графовой модели с помощью Neo4j.

Поэтому я считаю весьма вероятным, что в конечном итоге у вас будут разные нефункциональные требования к обоим. Чтобы иметь возможность разрешить различную конфигурацию для них, вы должны будете использовать отдельные экземпляры Event Processor для обоих. Обработчик событий, компонент, отвечающий за управление техническим аспектом предоставления событий вашим обработчикам событий, как место для настройки таких вещей, как обработка исключений, номера потоков, размеры пакетов и т. Д. c.

Обратите внимание, что процессоры событий бывают двух видов: SubscribingEventProcessor и TrackingEventProcessor. Вскоре их можно описать как событие pu sh и механизм извлечения событий, последний из которых является значением по умолчанию, поскольку он обеспечивает дальнейшую сегрегацию.

Для настройки отдельных обработчиков событий для обоих можно использовать конфигурацию API предоставлен Axon. Для обработчика событий это означает взаимодействие с EventProcessingConfigurer. С его помощью вы можете определить различные обработчики событий, а затем назначить компоненты обработки событий нужному экземпляру. Сокращение, которое вы можете использовать, - добавить аннотацию @ProcessingGroup к обоим компонентам обработки событий с разными именами. Особенно, если вы находитесь в среде Spring Boot, этого будет достаточно для настройки.

Эта сегрегация гарантирует, что сценарий исключений ios в пределах RegistrationNeo4jEventHandler не сможет оказать нежелательного влияния на RegistrationSqlEventHandler и наоборот.


Во-вторых, давайте перейдем к другому вопросу:

Во-вторых, как нам полностью прекратить повторную попытку события в случае сбоя?

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

  1. ListenerInvocationErrorHandler -> Ответственный за обработку исключений, генерируемых аннотированными методами @EventHandler.
  2. ErrorHandler -> Ответственный за обработку исключения, выданного в обработчике событий.

Реализации по умолчанию для них будут соответственно регистрировать ошибки (с LoggingErrorHandler) и распространить исключение (с PropagatingErrorHandler).

К вашему сведению, справочное руководство имеет это , чтобы сказать об обработке ошибок для обработчиков событий.

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

Однако, если эти четыре обработчика событий Примерами являются лишь обновление модели запроса, тогда последующий вызов должен просто выполнить ту же операцию без каких-либо побочных эффектов. Однако если эти обработчики событий выполняют какую-либо другую (внешнюю) деятельность, такую ​​как отправка электронного письма, это определенно гарантирует разделение данного компонента обработки событий в отдельный обработчик событий, который вы бы не хотели повторять / повторять.

...