Обработчик событий воспроизводится при перезапуске приложения?

Я играю с сервером аксона локально. Я запускаю док-контейнер на своем локальном компьютере с помощью команды docker run -d --name axonserver -p 8024:8024 -p 8124:8124 axoniq/axonserver.

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

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

flsh.axon.LetterSchedulingHandler   : Sending letter 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f...
flsh.axon.LetterSchedulingHandler   : Sending letter 6b4f6966-85ea-46e0-9c49-21bcd501a1b5...
flsh.axon.LetterSchedulingHandler   : Sending letter fc36292f-c7bd-4575-b56f-130624a87466...

flsh.axon.Letter                    : LetterScheduledEvent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SCHEDULED
flsh.axon.Letter                    : LetterScheduledEvent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SCHEDULED
flsh.axon.Letter                    : LetterScheduledEvent fc36292f-c7bd-4575-b56f-130624a87466 SCHEDULED
flsh.axon.Letter                    : Letter sent fc36292f-c7bd-4575-b56f-130624a87466 SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent 0e94035a-ec4b-4fdc-b8b6-4c0bc1927c8f SENT
flsh.axon.Letter                    : Letter sent fc36292f-c7bd-4575-b56f-130624a87466 SENT
flsh.axon.Letter                    : Letter sent 6b4f6966-85ea-46e0-9c49-21bcd501a1b5 SENT

Мой обработчик событий выглядит так:

@Slf4j
@Component
public class LetterSchedulingHandler {

    private final CommandGateway commandGateway;

    public LetterSchedulingHandler(CommandGateway commandGateway) {
        this.commandGateway = commandGateway;
    }

    @DisallowReplay //this doesn't seem to work
    @EventHandler
    public void handle(BeginSendLetterEvent event) {
        log.info("Sending letter {}...", event.getLetterId());
        commandGateway.send(new LetterSentCommand(event.getLetterId()));
    }
}
@CommandHandler
public void handle(LetterSentCommand cmd) {
    AggregateLifecycle.apply(new LetterSentEvent(cmd.getLetterId()));
}

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

@CommandHandler
public Letter(ScheduleLetterCommand cmd, EventScheduler scheduler) {
    String id = cmd.getLetterId();
    log.info("Received schedule command for letter id {}", id);
    ScheduleToken scheduleToken = scheduler.schedule(Duration.ofSeconds(5), new BeginSendLetterEvent(id));
    AggregateLifecycle.apply(new LetterScheduledEvent(id, scheduleToken));
}

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

axon:
  axonserver:
    servers: localhost
  eventhandling:
    processors:
      LetterSchedulingHandler:
        mode: subscribing

person GoldFlsh    schedule 22.01.2020    source источник


Ответы (1)


То, что вам не хватает @GoldFLsh, может быть одним из этих двух:

  1. Правильно укажите EventProcessor за вашим LetterSchedulingHandler
  2. Определите @ProcessingGroup вашего LetterSchedulingHandler

Что вы могли прочитать в Справочном руководстве по Обработчики событий, так как любой компонент обработки событий (прочтите, например, LetterSchedulingHandler) будет сгруппирован с другими компонентами обработки событий либо в процессоре подписки, либо в процессоре отслеживания событий.

Однако на данном этапе вы не настроили имя группы обработки. Это означает, что для группы обработки LetterSchedulingHandler по умолчанию будет использоваться имя пакета обработчика. Следовательно, в вашем файле свойств вы должны использовать имя пакета вместо LetterSchedulingHandler, чтобы определить его как подписывающийся.

Что еще яснее, так это добавить аннотацию @ProcessingGroup к LetterSchedulingHandler, дав ему четкое имя, которое затем можно будет использовать в файле свойств.

Наконец, тот факт, что вы неправильно ссылаетесь на обработчик событий, является причиной того, что вы увидите повторы событий. Axon по умолчанию использует TrackingEventProcessor, который отслеживает, насколько далеко он продвинулся до обработки событий потока. Без модуля сохранения состояния для хранения этих TrackingTokens он всегда будет начинаться с нуля.

person Steven    schedule 23.01.2020
comment
Похоже, в моем application.yaml тоже была ошибка, путь к свойству неверен, он также должен включать в себя обработку событий. Должен ли я просто отредактировать вопрос или вы должны добавить эту деталь к своему ответу? :) Я также должен был дать другие рекомендации в вашем ответе. - person GoldFlsh; 25.01.2020
comment
Похоже, когда я это сделал, у меня появилась эта ошибка - ›Description: A component required a bean named 'eventBus' that could not be found. Bean method 'eventStore' in 'AxonAutoConfiguration' not loaded because @ConditionalOnBean (types: org.axonframework.eventsourcing.eventstore.EventStorageEngine; SearchStrategy: all) did not find any beans of type org.axonframework.eventsourcing.eventstore.EventStorageEngine - person GoldFlsh; 25.01.2020
comment
Удаление processors.{name}.source: eventbus исправило это ... - person GoldFlsh; 25.01.2020
comment
EventBus будет источником по умолчанию, да, так что его можно пропустить. И вы правы, что упустили eventhandling часть в файле общих свойств. Я взял на себя смелость соответствующим образом скорректировать выборку. - person Steven; 27.01.2020