Wątek przeniesiony 2022-05-16 15:06 z Dev/ops przez cerrato.

Mikroserwisy a wspólne dane

0

Witam,
załóżmy, że mamy 2 najprostsze mikroserwisy:

  • UserService od użytkowników, ich autoryzacji, generowania tokenów itd. używający swojej bazy danych
  • PostService - od obsługi postów na tablicy używający swojej bazy danych

Dodając post na tablicy chcielibyśmy zapisywać dane użytkownika, który dodał post. Możemy po prostu zapisać jego id w bazie PostService. Ale żeby wyświetlić jego dane musimy poźniej przez api wywołac jakieś np. userservice/{id}/details i to za każdym razem gdy chcemy wiedzieć coś o dodajacym. Czy to jest poprawne podejście ? Gdy chcemy wyświelić listę 20 postów, każdy post musi odwołać się do serwisu i pobrac informacje kogo to post ?
Żeby to ominąć mogę zrobić tabele users w PostService i zapisywać tylko nazwę użytkownika w tej tabeli, wtedy nie muszę zawsze się odwoływać do drugiego serwisu. Ale co jeśli edytuje dane użytkownika ? Jego nazwę? To chyba traci sens mikroserwisu. Ale jednak jakoś trzeba to zmapować.
To jest tylko prosty przykład, ale takich wspólnych danych może być bardzo dużo. Jak się do tego odnosić?

PS. Wiem, że ktoś może napisać, że może lepszy monolit, nie bawić się w mikroserwisy. Ale chciałbym poznać optymalne rozwiązanie używając podejścia w mikroserwisami. Jeśli ktoś pracuje nad takimi projektami, mógłby opisać jak to działa w praktyce? :)

7

Moim zdaniem posty i autorzy postów to jest ta sama domena i to powinno być w jednym mikroserwisie.
Konto użytkownika i autoryzacja to inna domena a więc inny mikroserwis. W tym pierwszym mikroserwisie
przechowywałbym jakieś podstawowe informacje o autorze, które byłyby snapshotem z tego drugiego mikroserwisu.
Jeżeli konto użytkownika się zmieni można np. puścić jakiś event na kolejkę, że konto użytkownika się zmieniło i ten
pierwszy serwis mógłby nasłuchiwać na tym evencie i zaktualizować sobie dane po swojej stronie. Natomiast jeśli wyświetlamy
konkretny post wtedy jakiś BFF może połączyć te dane i dociągnąć więcej info o autorze z tego drugiego serwisu np. jakiś dłuższy
opis o autorze. Ja bym tak do tego podszedł.

5

Ja bym zrobił to tak:
do tabeli z postami dodajesz dwie kolumny - ID_autora oraz nick_autora. Podczas zapisu posta ustawiasz te dwie wartości. W ten sposób unikasz problemu, który słusznie zdiagnozowałeś, czyli przy wyświetlaniu 20 postów, 20 razy trzeba odpytać tabelę z loginami.

A jak rozwiązać kwestię zmiany nicka, albo ogólnie synchronizacji? Ja bym to zrobił tak, że jak user zmienia nick to wtedy na tabeli z postami dajesz UPDATE posty SET nick_autora="nowy_nick" WHERE nick_autora="stary_nick"

3

Rozwiązania:

  • wszystko w jednym serwisie: najprościej, ale nie jest modnie
  • Pytasz za każdym razem o userów. Możesz zrobić endpoint, który pozwala na zwrócenie 20 userów na raz. To podejście można przyśpieszyć jakimś in-memory cachem, ale pozostaje problem "inwalidacji" cache
  • Każda zmiana w UserService triggeruje komunikat do PostService. Fajne, ale skomplikowane i jest duża szansa, że coś się popsuje

Generalnie uważam, że problem jest trochę źle rozdzielony na mikroserwisy, bo masz bardzo dużą zależność pomiędzy PostService -> UserService. Prawdopodobnie zacząłbym od monolitu, jak nie to podejście z komunikatami bo jednak cachowanie w przypadku forum jest słabe, bo zależy nam na aktualnych danych

5

Redundancja danych to coś normalnego w świecie mikroserwisów, a temat tak naprawdę zaczyna się od zaprojektowania bounded contekstów. Jeżeli jakieś dane znajdują się w kilku serwisach (czyli bazach lub tabelach), to ich modyfikacja musi rozpropagować się na wszystkie te miejsca.

Dlatego najlepiej trzymać ID, a resztę odciągać z innego serwisu. Z pomocą w takiej sytuacji przychodzą tez read modele.

0

Można to zrobić na wiele sposobów. Np.
Użytkownik loguje się przy użyciu JWT w którym są jego dane, w razie czego można je doczytać i zapisać razem z postem.
W przypadku zmiany nicka usługa obsługująca konta wysyła wiadomość po topic'ach, że taka a taka zmiana miała miejsce, wszystko co tego potrzebuje nasłuchuje i robi update danych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1