Model współdzielonej domeny między różnymi mikrousługami

61

Wyobraź sobie scenariusz dwóch różnych mikrousług. Jeden do obsługi uwierzytelniania w ramach usługi, drugi do zarządzania użytkownikami. Obaj mają pojęcie użytkownika i będą rozmawiać o użytkownikach poprzez wzajemne połączenia.

Gdzie jednak powinien być model domeny „użytkownika”? Czy oboje mieliby inną reprezentację tego, co użytkownik jest na poziomie bazy danych? A jeśli mamy UserDTO do wykorzystania w wywołaniach API, czy oboje mieliby jeden dla swoich API?

Jakie jest ogólnie przyjęte rozwiązanie tego rodzaju problemu architektonicznego?

Kristof
źródło

Odpowiedzi:

36

W architekturze Microservices każda jest całkowicie niezależna od innych i musi ukrywać szczegóły wewnętrznej implementacji.

Jeśli podzielasz ten model, łączysz mikrousługi i tracisz jedną z największych zalet, w których każdy zespół może rozwijać swoją mikrousługę bez ograniczeń i konieczności poznania, jak ewoluują inne mikrousługi. Pamiętaj, że możesz nawet używać różnych języków w każdym z nich, byłoby to trudne, jeśli zaczniesz parować mikrousługi.

Jeśli są zbyt spokrewnieni, może są tacy, jak twierdzi @soru.

Powiązane pytania:

gabrielgiussi
źródło
21
Nie mogę się całkowicie zgodzić, jeśli są całkowicie niezależni, to masz 2 monolity. Chodzi o to, aby mieć inteligentne punkty końcowe i głupie rury. W kontekście korporacyjnym kończysz (obecnie mój koszmar) uderzając w ścianę, ponieważ istnieje domyślny model wspólnej domeny (domyślny, ponieważ go nie przewidzieliśmy), a każda usługa odkrywa na nowo% koła. A ekosystem mikro-usług rośnie, koncentrując się w 100% na funkcjonalności i własności zespołu, co popsuło go modelem domeny. Mamy zespoły tworzące nowe usługi, konsumujące inne, dublujące wiele wysiłku. Wciąż nierozwiązane.
juanmf,
5
Odłożyliśmy również na bok bardzo ważne wymaganie dotyczące architektury, niefunkcjonalne, wydajność. Usługi te wymagające danych wyjściowych innych usług, renderują wielopoziomowe podejście komunikacyjne dla każdego klienta RQ. Dodanie opóźnienia, którego nie można rozwiązać, chyba że zostanie dokonany ciężki refaktor i możliwe połączenie mikrousług.
juanmf
3
Ponadto, nie mając wspólnego zrozumienia modelu domeny, spowodowało, że zespoły zastosowały niepotrzebne „odblokowywanie i transformacje obiekt-obiekt” w celu dostosowania odpowiedzi mikrousług do modelu przyjętego przez wywołującą mikrousługę. Wiem, że połączenie wszystkich usług z biblioteką wspólnego modelu domeny może powodować inne problemy operacyjne, ale żadna z opcji nie jest satysfakcjonująca.
juanmf
3
@juanmf Byłoby bardzo cenne, gdybyś mógł zadać pytanie dotyczące swoich problemów. Interesuje mnie również wysłuchanie opinii w tej sprawie ...
Milos Mrdovic
1
Spróbuję usiąść i napisać coś, co ma sens
juanmf
13

Jeśli dwie usługi są na tyle powiązane, że ich wdrożenie bez współdzielenia DTO i innych obiektów modelu byłoby utrudnieniem, to silny znak, że nie powinieneś mieć dwóch usług.

Z pewnością ten przykład nie ma sensu jako dwie usługi; trudno wyobrazić sobie specyfikację „zarządzania użytkownikami” tak skomplikowaną, że cały zespół byłby tak zajęty, że nie mieliby czasu na uwierzytelnianie.

Gdyby z jakiegoś powodu tak było, komunikowaliby się za pomocą dowolnych ciągów, tak jak w OAuth 2.0 .

soru
źródło
4

Możesz myśleć o nich jak o dwóch osobnych ograniczonych kontekstach (w języku projektowania opartego na domenie). Nie powinny udostępniać między sobą żadnych danych oprócz identyfikatora używanego do korelowania „użytkownika” kontekstu uwierzytelnienia z „użytkownikiem” innego kontekstu. Każdy z nich może mieć własną reprezentację tego, czym jest „Użytkownik”, i swój własny model domeny, który to tylko informacje potrzebne do wykonywania obowiązków biznesowych.

Pamiętaj, że model domeny nie próbuje modelować „rzeczy” ze świata rzeczywistego, ale czym jest ta rzecz w określonym kontekście (takim jak Zarządzanie Tożsamością / Autoryzacją lub Zasoby Ludzkie itp.).

pnschofield
źródło
2

Obaj mają pojęcie użytkownika i będą rozmawiać o użytkownikach poprzez wzajemne połączenia.

Zgadzam się również z tym, co powiedział @soru. Jeśli jedna usługa potrzebuje danych innej usługi, ich granice są nieprawidłowe.

Dobrym rozwiązaniem jest to, co wymyślił @pnschofield - traktując twoje usługi jako kontekst Ograniczony.

Mówiąc o tym, krótko mówiąc: modele współdzielonych domen zabijają autonomię usług, zmieniając system mikrousług w rozproszony monolit. Co jest najwyraźniej gorsze niż monolit.

Pozostaje więc ogólne pytanie nierozwiązane - jak zdefiniować granice usługi lub kontekstu, aby rozwijały się one w wysokiej spójności i luźnej dobroci łączenia.

Wymyśliłem rozwiązanie, aby traktować moje konteksty jako możliwości biznesowe. Jest to wyższa odpowiedzialność biznesowa, funkcjonalność biznesowa, przyczyniająca się do ogólnego celu biznesowego. Możesz myśleć o nich jako o krokach, które Twoja organizacja musi przejść, aby uzyskać wartość biznesową.

Moja typowa sekwencja kroków, które podejmuję podczas identyfikowania granic usług, jest następująca:

  1. Zidentyfikuj możliwości biznesowe wyższego poziomu. Zazwyczaj są one podobne wśród organizacji z tej samej domeny. Możesz poczuć, jak to wygląda, sprawdzając model łańcucha wartości Portera .
  2. W ramach każdej możliwości zagłębiaj się głębiej i określ możliwości podrzędne.
  3. Zwróć uwagę na komunikację między możliwościami. Zobacz, co robi organizacja. Zwykle komunikacja koncentruje się w obrębie możliwości, powiadamiając resztę o wyniku swojej pracy. Dlatego przy wdrażaniu architektury technicznej Twoja usługa powinna również komunikować się za pośrednictwem zdarzeń. Ma to wiele pozytywnych konsekwencji. Dzięki takiemu podejściu Twoje usługi są autonomiczne i spójne. Nie potrzebują komunikacji synchronicznej i transakcji rozproszonych.

Prawdopodobnie przykład tej techniki byłby dla ciebie interesujący. Nie wahaj się i daj mi znać, co myślisz, ponieważ uważam to podejście za bardzo opłacalne. Pewnie, że może to również zadziałać.

Zapadło
źródło
1

Mikrousługa nie polega na „udostępnianiu niczego”, ale „udostępnianiu jak najmniej”. W większości przypadków „Użytkownik” jest naprawdę powszechnym bytem (tylko dlatego, że Użytkownik jest identyfikowany przez jakiś wspólny identyfikator - userId / email / phone). Tego rodzaju jednostki wspólne z definicji. Model użytkownika jest poza zakresem jednej mikrousługi. Musisz więc mieć jakiś globalny schemat, w którym powinien znajdować się Użytkownik (tylko ich najczęstsze pola). W ściśle określonym przypadku jest to tylko identyfikator.

Evgeniy Ostapenko
źródło