Obecnie mam dwie mikrousługi. Zadzwonimy do nich A
i B
.
Baza danych w ramach mikrousługi A
zawiera następującą tabelę:
A
|-- users
Baza danych w ramach mikrousługi B
zawiera następującą tabelę:
B
|-- trackers
Wymagania mówią o tym users
i trackers
mają relację wiele do wielu.
Nie jestem pewien, jak właściwie sobie z tym poradzić w architekturze mikrousług.
Widziałem, jak działa to na jeden z trzech sposobów:
user_trackers
Tabeli dodaje microserviceA
. Działa to podobnie do tabeli łączenia zawierającej „klucze obce” dousers
itrackers
.owners
Tabeli dodaje microserviceB
. Ta tabela działa podobnie do polimorficznej tabeli łączenia. Umożliwiłoby to dowolnej usłudze utworzenie powiązania z modułem śledzącym. Może to wyglądać mniej więcej tak:B |-- trackers |-- owners |-- owner_id |-- owner_type |-- tracker_id
- Przechowuje dokumentację
users
itrackers
na każdym microservice. Synchronizuj je z jakimś systemem pubsub.
Pierwotnie zamierzałem wybrać opcję 2, ponieważ podobało mi się, że zachowała granice transakcji. Mogę stworzyć moduł śledzący i powiązać go z czymś atomowo. Wydaje się jednak, że nie jest to możliwe w przypadku mikrousług B
. Dlaczego mikrousługa powinna B
przejmować się tym, że mikrousługa A
chce utworzyć powiązanie?
Wydaje mi się, że prawdopodobnie jest tutaj dobry wzór, którego nie jestem świadomy. Czy którakolwiek z przedstawionych opcji ma sens? Czy istnieje inna opcja, która może mieć większy sens?
źródło
Odpowiedź Zapadlo zawiera wiele dobrych informacji i uzasadnień. W tym miejscu dodam kilka praktycznych porad, które mogą pomóc w rozwiązaniu twoich problemów i porad w tej odpowiedzi.
Sposób, w jaki sformułowałeś swoje pytanie projektowe, dotyczy struktur bazy danych i jak dopasować do tego nowe wymagania dotyczące twoich struktur. Oznacza to, że budujesz projekt usługi na podstawie modelu danych. Na przykład nie widzę, w jaki sposób można uzyskać dostęp do relacji między użytkownikami a modułami śledzącymi lub z nich korzystać.
W projektowaniu usług najważniejsza jest konstrukcja interfejsu. W rzeczywistości wdrożenie jest prawie nieistotne w porównaniu, szczególnie w przypadku mikrousług. Powodem jest to, że po wdrożeniu usługi wszystkie zależności od usługi powinny istnieć tylko w interfejsie. Jeśli masz rację, powinieneś być w stanie całkowicie przepisać implementację bez żadnego konsumenta. I to jest główna zaleta autonomii. Nikt nie dba o to, jak go zbudowałeś. Potrzebują go tylko do działania w sposób, w jaki się komunikowałeś.
Zanim ktokolwiek zdoła ustalić, jak to wygląda w bazie danych lub gdzie tego chcesz, naprawdę musisz wyjaśnić, w jaki sposób te informacje będą wykorzystywane. Czy jest to coś, co zostanie ujawnione za pośrednictwem usługi, czy jest to jakiś rodzaj danych, które chcesz przemieścić w celu analizy?
Na marginesie, unikałbym zależności dwukierunkowych prawie za wszelką cenę. Jeśli masz zależności, naprawdę chcesz, aby tylko jedna strona wiedziała o drugiej. Gdy zależności są w obu kierunkach, usługi stają się zasadniczo jednostką atomową.
źródło
Wiele z nich sprowadza się do samej domeny. Jeśli użytkownik z zerowymi modułami śledzącymi nie ma sensu, usługa użytkownika musi wiedzieć o modułach śledzących. Jeśli moduł śledzący musi mieć użytkownika, musi on wiedzieć o użytkownikach. Jeśli coś takiego jak posiadanie trackera z wieloma właścicielami lub możliwość przeniesienia trackera od jednego użytkownika do drugiego ma sens, być może ta informacja należy do innej usługi.
źródło
Pytanie: Dlaczego twoje dane są rozdzielane wzdłuż Datatables?
Zazwyczaj wybrałbym opcję 3: usługi są całkowicie oddzielne i mogą odpowiedzieć na pytania, na które mogą potrzebować odpowiedzieć. Ponadto są o wiele bardziej odporne. Ale bądź ostrożny, twoje usługi mogą się zsynchronizować, jeśli przegapią zdarzenia, ale można to rozwiązać dzięki ostatecznej spójności.
Możesz również rozważyć połączenie obu usług - jeśli oba nie są w stanie odpowiedzieć bez wiedzy o sobie, po prostu scalę je, ponieważ prawdopodobnie są one częścią jednej domeny.
źródło