Нужна ли проекту CQRS инфраструктура обмена сообщениями, такая как NServiceBus?

Кривая обучения за последние 6 месяцев была сложной, главными виновниками были CQRS и DDD.

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

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

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

Итак, нужно ли мне использовать инфраструктуру обмена сообщениями, такую ​​как NServiceBus (даже несмотря на то, что базы данных чтения и записи находятся на одном компьютере) или у меня есть другие варианты? Да, есть кривая обучения, но я полагаю, что было бы чертовски многому научиться, если бы я ее не использовал.

Кроме того, я не хочу добавлять слой, если в этом нет необходимости.

Мысли?


person JD.    schedule 14.10.2012    source источник


Ответы (2)


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

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

Итак, нужно ли мне использовать инфраструктуру обмена сообщениями, такую ​​как NServiceBus (даже несмотря на то, что базы данных чтения и записи находятся на одном компьютере) или у меня есть другие варианты?

Это зависит от нескольких вещей. С чем вы часто сталкиваетесь в системе CQRS, так это с необходимостью публикации/подписки, когда несколько подсистем публикуют события, на которые подписывается система запросов/кэширования. Если вы видите потребность в pub/sub помимо простого обмена сообщениями точка-точка, используйте что-то вроде NServiceBus. Кроме того, я бы не стал сразу отказываться от использования NServiceBus, даже если он вам не нужен для целей масштабируемости, потому что я думаю, что логическое разбиение полезно само по себе. С другой стороны, как вы указываете, добавление уровней сложности обходится дорого, поэтому сначала попробуйте посмотреть, будет ли работать самая простая из возможных вещей.

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

person eulerfx    schedule 14.10.2012
comment
Большое спасибо за информацию. Я посмотрю на шаблон модели чтения. Вы упомянули версию по сущностям, вы имеете в виду по совокупным корням или по событиям? - person JD.; 15.10.2012

Нужна ли проекту CQRS инфраструктура обмена сообщениями, такая как NServiceBus?

Краткий ответ: нет.

Я впервые слышу о «шаблоне чтения-модели», упомянутом eulerfx. Это достаточно красивое имя, но есть еще кое-что:

Общая идея части «запрос» состоит в том, чтобы запросить денормализованное представление ваших данных. В ссылке «шаблон модели чтения» вы заметите, что запрос, используемый для заполнения модели чтения, делает некоторые подъемы. В упомянутом примере требуемая обработка данных не так сложна, но что, если она становится более сложной? Вот где вступает в действие деномализация. Когда вы выполняете свою «командную» часть, следующим действием будет денормализация данных и сохранение результатов для удобства чтения. Всю тяжелую работу должен выполнять ваш домен.

Вот почему вы спрашиваете об обмене сообщениями. Здесь есть несколько техник:

  • денормализованные данные в той же базе данных, той же таблице, разных столбцах
  • денормализованные данные в той же базе данных, в другой таблице
  • денормализованные данные в другой базе данных

Это хранилище. Как насчет консистенции?:

  • сразу последовательный
  • в конечном итоге последовательный

Самое простое решение (быстрый выигрыш) — денормализовать ваши данные в вашем домене, а затем, после сохранения объектов вашего домена через репозиторий, вы немедленно сохраняете деномарлизованные данные в то же хранилище данных, те же таблицы (таблицы), разные столбцы. 100% согласованность, и вы можете сразу начать чтение денормализованных данных.

Если вы действительно хотите, вы можете создать отдельный набор объектов для передачи этих данных, но проще просто написать простой слой запроса, который возвращает некоторый объект, переносящий данные, предоставленный вашей инфраструктурой доступа к данным (в в случае .Net это будет DataRow/DataTable). Абсолютно не повод для фантазии. Всегда будут исключения, но тогда вы можете пойти дальше и написать контейнер данных.

Для возможной согласованности вам понадобится некоторая форма организации очереди и связанной с ней обработки. Вы можете развернуть свое собственное решение или выбрать служебную шину. Это зависит от вас и вашего времени / технических ограничений :)

Кстати: у меня есть бесплатная служебная шина с открытым исходным кодом:

Любая обратная связь будет приветствоваться. Но подойдет любая старая служебная шина (MassTransit/NServiceBus/и т.п.).

Надеюсь, это поможет.

person Eben Roux    schedule 16.10.2012
comment
Хорошо законченный ответ. Интересный проект (Шаттл) - сейчас изучаю. - person Karell Ste-Marie; 26.10.2012
comment
Если я использую разные таблицы для своих денормализованных данных (ваш второй вариант), правильно ли я говорю, что постоянство домена и денормализованные данные будут в одной и той же транзакции? - person JD.; 11.11.2012
comment
@JD: это будет зависеть от того, насколько последовательными вам нужны ваши данные. Если абсолютно необходимо, чтобы он был на 100% непротиворечивым (например, баланс счета), то да; если ваши данные запроса могут быть устаревшими на некоторое время, вам не нужно использовать ту же транзакцию. - person Eben Roux; 12.11.2012