Учитывая Axon в новом проекте - PullRequest
3 голосов
/ 19 января 2020

Я начну проект с нуля через несколько месяцев.
Проект будет содержать множество бизнес-логи c, распределенных по нескольким subdomains. Да, мы будем использовать принципы Domain Driven Design. Технология будет состоять из Spring, Spring Boot & Hibernate стека.

Я искал несколько Java библиотек для покрытия инфраструктурных вещей, таких как:

  • domain event publication
  • event store
  • event deduplication
  • resequencers на стороне потребителя
  • projections
  • reliable publishing
  • reliable delivery & redelivery
  • ...

Я наткнулся на Axon Framework. Я уже слышал об этом, не знал этого в деталях. Поэтому я прочитал некоторые посты в блоге, немного документации и посмотрел некоторые трансляции на Youtube.

Кажется, это очень многообещающе, я собираюсь использовать его, потому что я не хочу изобретать, чтобы снова и снова крутиться на инфраструктурная сторона.
Так что я ищу кого-то, чтобы ответить и уточнить мои вопросы:

Обработка команд

Использование аксонов CommandHandlers с void методами. Можно ли заставить их возвращать значение (например, сгенерированный бизнес-идентификатор) или объекты для целей уведомления, касающиеся бизнес-операции?
Для меня не проблема, что этот метод будет блокировать ввод-вывод.


Локальная или удаленная публикация событий домена

Я хочу иметь четкое разделение local против remote событий домена. Local domain события должны быть видны только для локального субдомена. Можно ли настроить потребление событий syn c и / или asyn c? Мои локальные доменные события могут быть «жирными». Им разрешено переносить больше данных, поскольку они не пересекают границы домена.

Remote domain events будет «тонким», поэтому для удаленных доменов необходимы только минимальные данные. События этого типа должны всегда обрабатываться asyn c.

Возможно ли преобразовать событие локального (толстого) домена в событие удаленного (тонкого) домена на краю домена? Под «краем» я подразумеваю инфраструктурную сторону. Таким образом, модели домена не нужно знать различие между локальными и удаленными событиями домена.


CQRS синхронно

Мое приложение будет состоять из 1 ( возможно 2) core domains и several subdomains. Некоторые домены содержат множество бизнес-логи c и потребуют CQRS.
Другой домен будет более «грубым». Можно ли сделать CQRS синхронно?
Я хочу начать этот путь, прежде чем добавлять технические сложности, такие как обработка asyn c. Это возможно с Axon?
Это также означает, что доменные события будут храниться в хранилище событий без использования event sourcing.

Можно ли использовать Axon's event store без поиска событий? То же самое для проекции, я просто хочу проецировать события домена для построения моей модели чтения.


Модульный монолит

Мы будем использовать modular monolith.
Не очень модно в наши дни со всеми вещами microservices. Хотя я убежден, что у меня есть монолит, в котором каждый домен полностью отделен (код приложения и схема DB), где операции будут обрабатываться с возможной согласованностью, а события домена содержат необходимые данные. Позже и, если необходимо, будет проще перейти на microservices architecture.

Является ли Axon платформой, подходящей для модульной монолитной архитектуры? Есть что-то, чтобы принять во внимание?


Полностью разделенная модель домена (постоянство агности c)

Модель домена будет полностью отделена от данных модель. Нам нужно иметь репозиторий, который читает модель данных (используя Hibernate) и использует data mapper для создания агрегата, когда его нужно загрузить.
Также необходим другой способ, агрегат необходимо преобразовать и сохранены в модель данных (с помощью картографа данных).
Кроме того, доменные события агрегатов необходимо сохранять в хранилище событий и публиковать в локальных или удаленных обработчиках событий.

Это имеет некоторые последствия:

  • нам нужно иметь полный контроль над реализацией репозитория, который взаимодействует с одним или несколькими DAO (хранилищами данных Spring), чтобы извлекать необходимые данные из сущностей Hibernate и создавать из них агрегат. В конце концов, агрегат может быть смоделирован в 2 или даже 3 реляционных таблицах.

  • нам не нужна аннотация Hibernate в модели предметной области

Возможен ли такой подход с Аксоном? Я вижу только примеры, использующие прямой JPA (доменные модели от 1 до 1 для сущностей) или источники событий.
Этот подход действительно является для нас преградой, модель с раздельными доменами дает гораздо больше возможностей, чем непосредственное сопоставление. к объектам данных.

Ниже приведен пример того, чего я хочу достичь:

Агрегирование (без JPA) в некотором пакете модели домена:

public class ScoringResultAggregate {
  // members, constructor, operation omitted for brevity
}

Hibernate Объект в некотором пакете инфраструктуры:

@Entity
@Table(name ="SOME_TABLE_NAME)
public class ScoringResultEntity {
  // member and getters & setters; no domain logic
}

Интерфейс репозитория, который принадлежит модели домена:

public interface ScoringResultRepository {
  void save(ScoringResultAggregate scoringResultAggregate);

  ScoringResultAggregate findByApplicationNumber(ApplicationNumber applicationNumber);
}

Адаптер, который реализует интерфейс репозитория; Ответственный за сопоставление агрегата из / в данные (JPA) модель:

class ScoringResultAdapterRepository implements ScoringResultRepository {
  private ScoringResultJpaRepository scoringResultJpaRepository;

  ScoringResultJPARepository(ScoringResultJpaRepository scoringResultJpaRepository) {
    this.scoringResultJpaRepository= scoringResultJpaRepository;

  public void save(ScoringResultAggregate scoringResultAggregate) {
    // converts aggregate to ScoringResultEntity and saves the state into DB
  }

  public ScoringResultAggregate findByApplicationNumber(ApplicationNumber applicationNumber) {
    // loads an ScoringResultEntity from DB and converts it into an aggregate
  }
}


Axon Server

Axon server выглядит очень многообещающе. Хотя это полезно только для event sourcing? Можно ли использовать его вместе с Sql БД, в которой хранятся агрегаты (сохранение состояния) и события домена сохраняются на сервере Axon?



Множество вопросов. Надеюсь, кто-то с опытом работы с Аксоном может мне помочь: -)

Ответы [ 2 ]

2 голосов
/ 20 января 2020

Я чувствую, что Джаспер говорит правильные вещи, но я также думаю, что могу подчеркнуть их немного больше:

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

  • Локальная или удаленная публикация событий домена - Джаспер ясно говорит об этом, и он прав. Ваше желание создать ограниченный контекст, для которого Axon Server (Enterprise) имеет поддержку. Если вы не будете использовать Axon, вам придется создать эту инфраструктуру самостоятельно.

  • CQRS синхронно - Axon отлично справляется с асинхронным и синхронным обменом сообщениями. Основное отличие заключается в том, что вы заблокируете результат отправки своих сообщений. Например, CommandGateway имеет метод send и sendAndWait, что обеспечивает вам диспетчеризацию команд syn c и asyn c. Наконец, совершенно нормально использовать Axon Server в качестве хранилища событий, не используя Event Sourcing. Event Sourcing - это выбор при использовании Axon, а не требование.

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

  • Модель полностью разделенных доменов (постоянство агности c ) - С помощью вашей модели запросов вы имеете полный контроль над тем, как вы хотите отобразить свою модель данных на фактическую модель, которую вы будете использовать. В терминах Aggregate in Axon следует рассматривать вашу Командную модель, для которой вы можете выбрать подход к хранилищу из источника или хранилище с сохранением состояния. Сохраненная в состоянии реализация, предоставляемая Axon Framework, работает на основе JPA, что потребует от вас установки некоторых аннотаций наряду с аннотациями аксонов в вашей модели команд. Если вам нужно отделить это, я мог бы представить, что вы создадите свой собственный вариант Repository и AggregateFactory. Опять же, подход Event Sourcing сделает вашу модель домена полностью свободной от аннотаций постоянства, поэтому я бы go за этот маршрут был честным.

  • Axon Server - Да, вы можете использовать Axon Server, даже если вы go сохраняете состояние подхода Aggregates. Знайте, что Axon Server, являющийся хранилищем событий, является унифицированным решением для маршрутизации команд, событий и запросов. Если вы перейдете от модульного монолита к настройке (микро) услуг, то наличие сервера Axon для выполнения всей маршрутизации сообщений сделает вашу жизнь очень, очень легкой.

2 голосов
/ 20 января 2020

Я надеюсь, что смогу ответить на некоторые из них, но я также не очень разбираюсь в использовании Axon:

Возвращаемые значения из обработчика команд - Да, это возможно. У нас был пример, в котором мы возвращаем сгенерированный агрегированный идентификатор (я не уверен на 100% в этом ответе)

Локальная или удаленная публикация событий домена - Да, сервер Axon ENTERPRISE (!) поддерживает многоконтекстные сборки для этой цели. https://axoniq.io/product-overview/axon-server-enterprise

CQRS синхронно - Вопрос не совсем ясен, но нет необходимости моделировать вашу полную систему с CQRS. Вы можете использовать CQRS для некоторых доменов и другую архитектуру для поддоменов.

Используйте Saga для любых «транзакций», подобных вещам. Откаты должны быть написаны разработчиком. Система не может сделать это для вас.

Модульный монолит - не должно быть технической проблемой.

Модель полностью разделенных доменов (постоянство агности c) - Вопрос не совсем ясен, но хранить только события на сервере Axon. Агрегаты создаются последовательностью агрегатов. Не используйте никакие другие данные для этого. Агрегат используется для обработки команд с помощью проверок состояния и применения новых событий.

Когда система получает командное сообщение, Axon Framework просматривает идентификатор агрегата и заново создает агрегат путем воспроизведения всех существующих события для этой совокупности. Затем метод @CommandHandler и тип командного сообщения вызывается в совокупности с состоянием системы. Не делай этого сам.

С другой стороны. Создавайте собственные пользовательские проекции (просматривайте модели), прослушивая события (@EventHandler) и сохраняйте данные в своем собственном формате для любых типов моделей / хранилищ данных. Вы можете, например, построить REST API поверх этого, чтобы использовать данные.

Axon Server - Используйте его там, где он создан. Используйте его как хранилище событий, а не для других целей.

См. Дополнительную информацию и почему: https://www.youtube.com/watch?v=zUSWsJteRfw

...