Jak szczegółowe powinno być polecenie w modelu CQ [R] S?

17

Zastanawiam się nad projektem migracji części naszego SOA opartego na WCF do modelu magistrali usług (prawdopodobnie nServiceBus) i za pomocą kilku podstawowych sub-pubów, aby osiągnąć separację poleceń i zapytań .

Nie jestem nowy w SOA, ani nawet w usługach modeli magistrali, ale przyznaję, że do niedawna moja koncepcja „separacji” ograniczała się do tworzenia kopii lustrzanych i replikacji. Mimo to pociąga mnie ten pomysł, ponieważ wydaje się, że zapewnia on wszystkie korzyści z ostatecznie spójnego systemu, jednocześnie omijając wiele oczywistych wad (w szczególności brak odpowiedniego wsparcia transakcyjnego).

Czytałem dużo na ten temat z Udi Dahan, który jest w zasadzie guru na architekturach ESB (przynajmniej w świecie Microsoft), ale jedno mówi naprawdę mnie zastanawia:

Gdy otrzymujemy większe jednostki z większą liczbą pól, otrzymujemy także więcej aktorów pracujących z tymi samymi jednostkami, a tym większe prawdopodobieństwo, że coś dotknie jakiegoś atrybutu w danym momencie, zwiększając liczbę konfliktów współbieżności.

[...]

Kluczowym elementem CQRS jest przemyślenie projektu interfejsu użytkownika, aby umożliwić nam uchwycenie intencji naszych użytkowników, dzięki czemu wybranie klienta jest inną jednostką pracy dla użytkownika niż wskazanie, że klient się przeprowadził lub że został żonaty. Używanie interfejsu użytkownika podobnego do programu Excel do zmiany danych nie wychwytuje zamiaru, jak widzieliśmy powyżej.

- Udi Dahan, Wyjaśnione CQRS

Z perspektywy opisanej w cytacie ciężko jest kłócić się z tą logiką. Ale wydaje się to sprzeczne z zasadą SOA. SOA (i tak naprawdę ogólnie usługi) mają radzić sobie z gruboziarnistymi wiadomościami , aby zminimalizować rozmowy sieciowe - wśród wielu innych korzyści.

Zdaję sobie sprawę, że gadanie w sieci nie stanowi większego problemu, gdy masz wysoce rozproszone systemy z dobrym kolejkowaniem wiadomości i bez bagażu RPC, ale nie wydaje się rozsądne całkowite odrzucenie problemu. Udi wydaje się niemal mówić, że każda zmiana atrybutu (tj. Aktualizacja pola) powinna być jego własnym poleceniem, co trudno sobie wyobrazić w kontekście jednego użytkownika potencjalnie aktualizującego setki lub tysiące połączonych jednostek i atrybutów, jak to często bywa w przypadku tradycyjnego Serwis internetowy.

Jedna aktualizacja wsadowa w programie SQL Server może zająć ułamek sekundy, biorąc pod uwagę dobrze sparametryzowane zapytanie, parametr o wartości tabeli lub wstawianie zbiorcze do tabeli pomostowej; przetwarzanie wszystkich tych aktualizacji pojedynczo jest powolne, wolne, wolne , a sprzęt bazy danych OLTP jest najdroższy ze wszystkich do skalowania w górę / w górę.

Czy jest jakiś sposób na pogodzenie tych konkurujących ze sobą obaw? Czy myślę o tym w niewłaściwy sposób? Czy ten problem ma dobrze znane rozwiązanie w świecie CQS / ESB?

Jeśli nie, to jak decydować, jaki powinien być „właściwy poziom” szczegółowości w poleceniu? Czy istnieje jakiś „standardowy” punkt, który można wykorzystać jako punkt wyjścia - coś w rodzaju 3NF w bazach danych - i odbiegać tylko wtedy, gdy staranne profilowanie sugeruje potencjalnie znaczącą poprawę wydajności?

Czy może jest to jedna z tych rzeczy, które pomimo wielu mocnych opinii różnych ekspertów, są w rzeczywistości kwestią opinii?

Aaronaught
źródło

Odpowiedzi:

7

Na temat „każdej zmiany atrybutu”

Myślę, że nie trafiłeś w sedno. Pan Udi Dahan mówi, że powinieneś uchwycić intencje użytkownika jako polecenie. Użytkownik końcowy obawia się, że może wskazać, że klient się przeprowadził. W zależności od kontekstu, w jakim polecenie może zawierać identyfikator klienta, nowy adres (z podziałem na ulicę, numer ulicy, kod pocztowy, ...), opcjonalnie nowy numer telefonu (nierzadko podczas przeprowadzki - może mniej w przypadku wszystkich tych telefonów komórkowych) . To nie jest jeden atrybut. Lepszym pytaniem jest „jak zaprojektować polecenia?”. Projektujesz je z perspektywy behawioralnej. Każdy przypadek użycia, przepływ, zadanie, które użytkownik końcowy próbuje wykonać, zostanie przechwycony w jednym lub kilku poleceniach. Dane, które idą w parze z tymi poleceniami, przychodzą naturalnie, gdy zaczniesz bardziej szczegółowo je rozumować. Na co należy zwrócić uwagę, należy interpretować dane jako „może oznaczać, że musisz podzielić polecenie. Mam nadzieję, że nigdy nie znajdziesz tego standardu w odniesieniu do szczegółowości poleceń. Dobre pytanie!

Yves Reynhout
źródło
Ta definicja wciąż wydaje mi się bardzo arbitralna; model koncepcyjny CSR może łączyć preferowany status i stan wojenny razem w taki sam sposób, jak łączymy adres i kod pocztowy razem. Nie chcę dzielić włosów, po prostu wydaje mi się, że aby naprawdę zrozumieć, czy są to różne zachowania, musisz być w stanie przewidzieć dalsze skutki, a OTOH całą ideę ESB i CQS oraz pub / sub jest taki, że nie powinieneś wiedzieć ani przejmować się tym, co dzieje się poniżej. Dziękuję za odpowiedź, ja to doceniam, choć nie mogę powiedzieć, że poczujesz się bardziej oświecony tak daleko ...
Aaronaught
@Aaronaught: Definicja jest dowolna. Szczegółowość polecenia powinna być taka, jaka ma sens w danym scenariuszu . Nie ma jednego rozmiaru dla wszystkich. Istnieje kilka wskazówek, takich jak dopasowywanie poleceń w celu użycia przypadków lub zadań lub akcji dostępnych w interfejsie użytkownika - innym jest preferowanie bardziej szczegółowych poleceń niż mniej szczegółowych poleceń (w szczególności, jak powiedział Yves, nieufny wobec danych interpretowanych jako przepływ kontroli logicznej) - ale nie ma twardych i szybkich zasad. Czy istnieje rzeczywisty scenariusz, w którym „jeden użytkownik potencjalnie aktualizuje setki lub tysiące połączonych jednostek i atrybutów”?
quentin-starin
To o to chodzi! Nie zbijaj razem. Podziel według zachowania! Nie umieszczaj danych w poleceniu, które nie jest zgodne z przeznaczeniem polecenia / użytkownika końcowego. I to nie dotyczy dalszych systemów.
Yves Reynhout,
@qes: W naszych systemach jest kilka takich scenariuszy, bardzo realnych i bardzo potrzebnych. Aby stwierdzić to tak prosto, jak to możliwe, muszą zmodyfikować całe sekwencje danych, a sekwencje te mają sens tylko jako sekwencje. Oczywiście zwykle nie rejestrują tych zmian po rekordach, stosują pewien algorytm, a następnie naprawiają kilka wyjątków. Może po prostu nie jest to odpowiedni scenariusz dla CQS, ale ta decyzja jest tylko częścią mojego szerszego pytania.
Aaronaught
1
@qes: Wystarczająco sprawiedliwe, a to samo w sobie odpowiedź. I na pewno rozumieją pojęcia logicznej operacji (to jak istniejące usługi są modelowane), myślę, że właśnie zostały zaniepokojony, że CQS wydaje się zmieniać kilka reguł wokół jak powinien zdefiniować operację. „Tradycyjne” SOA wydaje się zaczynać od najgrubszej możliwej definicji i, jeśli to konieczne, schodzić po drabinie abstrakcji; moje dotychczasowe rozumienie CQS wydaje się wskazywać na coś przeciwnego, zacznij od najbardziej szczegółowej możliwej definicji i abstrakcyjnej, jeśli zbytnio przypomina RPC lub przepływ kontrolny.
Aaronaught
2

Wiadomość, którą Udi próbuje przekazać, to fakt, że CQRS to coś więcej niż tylko CRUD. Dlaczego stworzyłem ten rekord? Dlaczego zmieniam ten rekord? Dlaczego jest usuwany / oznaczany jako usunięty?

Polecenia powinny odpowiadać działaniom / przypadkom użycia wykonywanym przez użytkownika w systemie i wyrażać zamiar działania, a nie tylko mówić o zmianie. Może się wydawać, że jest drobniej ziarnisty, ale może być znacznie grubszy niż się wydaje. Na przykład zmiana statusu na złoty może wymagać zmiany kilku atrybutów, a wiele innych agregatów może nawet zareagować i zmienić się w odpowiedzi na odpowiednie zdarzenie.

CQRS polega na uchwyceniu języka firmy w warstwie serwisowej, aby interfejs użytkownika nie musiał się martwić o to, co się stanie, kiedy dokonam aktualizacji statusu złota lub gdy przesyłka zostanie oznaczona przez przewoźnika jako niemożliwa do dostarczenia lub pracownik został awansowany do kierownika grupy technologicznej. Cóż, technicznie rzecz biorąc, mówię teraz o zaopatrzeniu w zdarzenia, ale rozumiesz. Istnieją bardziej wyraźne komunikaty, ale niekoniecznie są one bardziej szczegółowe niż standardowe CUD.

Michael Brown
źródło