Якою детальною має бути команда у моделі CQ [R] S?


17

Я розглядаю проект про переміщення частини нашого WCF на базі WCF на модель службової шини (можливо, nServiceBus) і використовую деякий базовий pub-sub для досягнення розділення команд-запитів .

Я не новачок у SOA або навіть у моделях службових шин, але, зізнаюся, до недавнього часу моя концепція "розділення" обмежувалася дзеркальним відображенням та реплікацією баз даних. Тим не менш, мене приваблює ця ідея, тому що, здається, вона забезпечує всі переваги системи, що є врешті-решт, одночасно уникаючи багатьох очевидних недоліків (особливо, відсутність належної підтримки транзакцій).

Я багато читав на цю тему від Уді Дахана, який в основному є гуру архітектури ESB (принаймні, у світі Microsoft), але одне, що він каже, нас справді спантеличує:

Оскільки ми отримуємо більші сутності з більшою кількістю полів, ми також отримуємо більше акторів, які працюють з тими ж сутностями, і чим більша ймовірність того, що в якийсь момент щось зачепить якийсь їх атрибут, збільшуючи кількість конфліктів одночасності.

[...]

Основним елементом CQRS є переосмислення дизайну користувальницького інтерфейсу для того, щоб ми могли зафіксувати наміри наших користувачів таким чином, щоб зробити перевагу клієнта іншою одиницею роботи для користувача, ніж вказувати на те, що клієнт перемістився або що він отримав одружився. Використання інтерфейсу, схожого на Excel, для зміни даних не передбачає наміру, як ми бачили вище.

- Уді Дахан, уточнений CQRS

З точки зору, описаного в цитаті, важко сперечатися з цією логікою. Але це, здається, йде проти зерна стосовно SOA. SOA (і справді сервіси загалом) повинні мати справу з грубозернистими повідомленнями , щоб мінімізувати мережеву балаканину - серед багатьох інших переваг.

Я усвідомлюю, що мережевий балаканин не викликає проблем, коли у вас високорозподілені системи з хорошою чергою повідомлень і жодним багажем RPC, але не видається розумним цілком відмовитись від проблеми. Udi майже здається, що кожна зміна атрибуту (тобто оновлення поля) повинна бути власною командою, що важко уявити в контексті того, що один користувач потенційно може оновлювати сотні чи тисячі об'єднаних об'єктів та атрибутів, як це часто відбувається з традиційними веб-сервіс.

Одне пакетне оновлення в SQL Server може зайняти частку секунди, отримавши хороший високопараметризований запит, табличний параметр або об'ємну вставку до інтерактивної таблиці; обробка всіх цих оновлень по одному відбувається повільно, повільно, повільно , а обладнання для баз даних OLTP є найдорожчим з усіх для масштабування та зменшення масштабів.

Чи є якийсь спосіб узгодити ці конкуруючі проблеми? Я думаю про це неправильно? Чи має ця проблема добре відоме рішення у світі CQS / ESB?

Якщо ні, то як вирішити, яким повинен бути "правильний рівень" деталізації в команді? Чи є якийсь "стандартний", який можна використовувати як вихідний пункт - на зразок 3NF в базах даних - і відхилятися лише тоді, коли ретельне профілювання припускає потенційно значну користь від продуктивності?

Чи, можливо, це одна з тих речей, яка, незважаючи на кілька висловлених різними експертами думок, насправді є лише питанням думки?

Відповіді:


7

На тему "кожна зміна атрибута"

Я думаю, ти пропустив справу. Містер Уді Дахан говорить, що ви повинні захопити наміри користувача як команду. Кінцевий користувач переймається можливістю вказати, що клієнт переїхав. Залежно від контексту, що команда може містити ідентифікацію клієнта, нову адресу (розділити на вулицю, номер вулиці, поштовий індекс, ...), необов'язково новий номер телефону (не рідкість, коли ви пересуваєтесь - можливо, менше, ніж для всіх цих мобільних телефонів) . Це навряд чи один атрибут. Краще питання - "як я конструюю команди?". Ви проектуєте їх з поведінкової точки зору. Кожен випадок використання, потік і завдання, які кінцевий користувач намагається виконати, будуть захоплені однією або декількома командами. Те, що стосується цих команд, відбувається природно, коли ви починаєте міркувати про них детальніше. На що слід стежити - це дані, які трактуються як "може бути вказівкою на те, що вам потрібно розділити команду. Я сподіваюся, що ви ніколи не знайдете цього стандарту щодо деталізації команд. Хороше запитання, хоча!


Це визначення досі відчуває мене дуже довільним; концептуальна модель КСВ може згуртовувати бажаний стан та воєнний стан разом так само, як ви збираєте одноразову адресу та поштовий індекс. Я не маю на увазі роздвоєння волосся, мені просто здається, що для того, щоб зрозуміти, чи відрізняються вони від поведінки, ви повинні мати можливість передбачити наслідки, пов'язані з низхідним потоком, і ототожнювати всю ідею ESB і CQS та паб / Під тим, що ви не повинні знати або дбати про те, що відбувається нижче за течією. Дякую за вашу відповідь, я ціную це, хоча не можу сказати, що відчуваю себе ще просвіченим досі ...
Aaronaught

@Aaronaught: визначення є довільним. Деталізація команди повинна мати будь-який сенс для вашого конкретного сценарію . Немає жодного розміру для всіх. Існує декілька вказівок, таких як відповідні команди для використання випадків, завдань або дій, доступних в інтерфейсі. Інше - віддати перевагу більш деталізованим командам над менш деталізованими командами (зокрема, як Ів сказав, що насторожено ставитесь до даних, що трактуються як логічний потік управління) - але жодного жорсткого і швидкого правила. Чи існує фактичний сценарій, коли "один користувач потенційно оновлює сотні чи тисячі об'єднаних об'єктів та атрибутів"?
квентін-зірин

У цьому вся суть! Не збивайтеся разом. Розділіться за поведінкою! Не вводьте дані в команду, яка не узгоджується з наміром команди / кінцевого користувача. І справа не в низхідній системі.
Ів Рейнхаут

@qes: У наших системах є кілька таких сценаріїв, дуже реальних і дуже необхідних. Щоб констатувати це якомога простіше, їм потрібно змінювати цілі послідовності даних, і ці послідовності мають сенс лише як послідовності. Звичайно, вони зазвичай не вносять ці зміни до запису, вони застосовують певний алгоритм до більшої частини, а потім виправляють кілька винятків. Можливо, це просто не підходящий сценарій для CQS для початку, але це рішення - лише підмножина мого більш широкого питання.
Aaronaught

1
@qes: Досить справедливо, і це відповідь сама по собі. Я, звичайно, розумію концепцію логічної операції (саме так моделюються існуючі сервіси). Я думаю, що мене просто хвилювало, що CQS, здається, змінює деякі правила щодо того, як вам слід визначити операцію. "Традиційне" SOA, здається, починається з найбільш грубого визначення та рухається вниз по сходах абстракції; моє розуміння CQS поки що, схоже, вказує на протилежне. Почніть з найбільш детального визначення та абстрактного, якщо він виглядає занадто схожим на RPC або контрольний потік.
Aaronaught

2

Повідомлення, яке Udi намагається зустріти, - це те, що CQRS - це не просто CRUD. Чому я створив цей запис? Чому я змінюю цей запис? Чому він видаляється / позначається як видалений?

Команди повинні відповідати випадкам дій / використання, які користувач робить із системою, і виражати наміри дії, а не просто говорити змінити це. Крім того, може здатися, що він тонше зернистий, але він може бути набагато грубішим, ніж спочатку з'являється. Наприклад, оновлення статусу золота може включати в себе зміну кількох атрибутів, а ряд інших агрегатів може навіть відповідати та змінюватися у відповідь на відповідну подію.

CQRS полягає у захопленні мови бізнесу на рівні Сервісу, тому користувальницький інтерфейс не повинен турбуватися про те, що станеться, коли я зробляю те, що оновлення статусу золота або відправлення було відмічене перевізником як недоставне, або працівника підвищено. керівнику групи технологій. Ну технічно я зараз говорю про події Sourcing, але ви отримаєте мій дрейф. Є більш чіткі повідомлення, але вони не обов'язково більш дрібнозернисті, ніж стандартні CUD.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.