Trudno mi uniknąć duplikacji danych lub wspólnej bazy danych dla nawet najprostszego projektu mikrousług, co sprawia, że myślę, że coś mi brakuje. Oto podstawowy przykład problemu, przed którym stoję. Zakładając, że ktoś używa aplikacji internetowej do zarządzania zapasami, potrzebowałby dwóch usług; jeden dla zapasów zarządzających towarami i ilością w magazynie oraz usługą użytkowników, która zarządzałaby danymi użytkowników. Jeśli chcemy przeprowadzić kontrolę tego, kto zaopatrzył bazę danych, moglibyśmy dodać identyfikator użytkownika do bazy danych dla usługi inwentaryzacji jako ostatni magazynowany według wartości.
Korzystając z aplikacji, możemy chcieć zobaczyć wszystkie wyczerpujące się produkty oraz listę osób, które je ostatnio zaopatrzyły, abyśmy mogli poprosić ich o ponowne uruchomienie. Korzystając z opisanej powyżej architektury, do usługi inwentaryzacyjnej zostanie wysłane żądanie pobrania szczegółów pozycji dla wszystkich towarów, których ilość jest mniejsza niż 5. Zwróci to listę zawierającą identyfikatory użytkowników. Następnie do serwisu użytkowników zostanie wysłane oddzielne żądanie uzyskania nazwy użytkownika i danych kontaktowych dla listy identyfikatorów użytkowników uzyskanych z usługi inwentaryzacji.
Wydaje się to okropnie nieefektywne i nie wymaga wielu innych usług, zanim wykonamy wiele żądań do interfejsów API różnych usług, które z kolei wykonują wiele zapytań do bazy danych. Alternatywą jest replikacja danych użytkowników w danych inwentaryzacyjnych. Gdy użytkownik zmieni swoje dane kontaktowe, będziemy musieli powtórzyć zmianę za pośrednictwem wszystkich innych usług. Ale to wydaje się nie pasować do ograniczonej kontekstowej koncepcji mikrousług. Możemy również użyć jednej bazy danych i udostępnić ją między różnymi usługami oraz mieć wszystkie problemy związane z integracją bazy danych .
Jaki jest właściwy / najlepszy sposób na wdrożenie tego?
źródło
Odpowiedzi:
Zupełnie tęskniłem za tym, gdzie trzeba skopiować.
Główną zasadą mikrousług jest to, aby usługa była pojedynczym organem. Oznacza to, że zarządzanie zapasami i użytkownikami może być całkowicie oddzielne. Zaprojektowałbym zarządzanie użytkownikami tak, aby nawet nie wiedziało, że istnieje system zapasów.
Ale zaprojektowałbym system ekwipunku, aby nigdy nie przechowywał niczego o użytkownikach innych niż ID użytkownika. To rozwiązuje problem propagowania zmian informacji o użytkowniku.
Jeśli chodzi o rzeczy, które wymagają zarówno informacji o inwentarzu, jak i informacji o użytkowniku, takich jak dzienniki, audyty i wydruki, nie są aktualizowane po zmianie informacji. Są zapisem tego, co było. Znowu nie propagujesz zmian.
Tak więc w każdym przypadku, gdy chcesz uzyskać najnowsze informacje o użytkowniku, pytasz serwis informacyjny użytkownika.
źródło
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join
Pamiętaj, że „idealnie” jest jeden sklep na usługę (lub więcej!). Nie ma więc czegoś takiego jak „łączenie” między „granicami”. Powód jest prosty: DB generuje sprzężenie między usługami. W przeciwieństwie do sugestii @CandiedOrange, myślę, że możemy zduplikować minimum danych z jednej usługi do drugiej. Mam na myśli dane, których zmiana jest mało prawdopodobna. Jeśli ten duplikat poprawi wydajność i wydajność (i oba są wymagane), „plusy” prawdopodobnie zrównoważyłyby „minusy”Według ebooka Microsoft na temat architektury mikrousług , duplikacja danych nie jest niczym złym. Zasadniczo duplikacja danych zwiększa rozdzielenie usług i tym samym wzmacnia ich rolę jako jednego organu. Odpowiedni fragment:
źródło
W rzeczy samej tak.
To prawda, że w monolicie można mieć model zapasów, w którym można wyszukiwać odpowiednie elementy, wprowadzać je do modelu użytkownika i uzyskiwać te same dane.
Lub możesz pójść dalej, jeśli masz je w tej samej relacyjnej bazie danych i napisz SQL, a baza danych zajmie tabelę inwentarza i tabelę użytkownika, to trochę magii i otrzymasz dane, których szukasz.
Niezależnie od tego, jak to robisz, gdzieś tam będzie kod, który zasadniczo pobiera listę identyfikatorów użytkowników z systemu ekwipunku, podaje je do systemu użytkownika i kompiluje listę danych.
Pytanie, na które musisz odpowiedzieć, dotyczy wydajności i konserwacji oraz innych „miękkich” cech.
Główną zaletą mikrousług jest skalowanie. Jeśli masz dziesięć tysięcy użytkowników na jednym komputerze i jest to trochę powolne, możesz dodać inną maszynę, a system staje się dwa razy szybszy. Dodaj jeszcze osiem, a to dziesięć razy szybciej. (Skalowanie liniowe jest prawdopodobnie optymistyczne, ale jest idealne i nie jest to nierozsądne nadziei).
I to jest za usługę . Jeśli system inwentarza stanowi wąskie gardło, jest używany do więcej niż raportów o użytkownikach, możesz dodać więcej maszyn tylko do tej usługi . Maszyny mogą być również wyspecjalizowane; ta usługa wymaga dużo pamięci, ta usługa wykonuje ciężkie obliczenia i potrzebuje więcej procesora.
Jeśli skalowanie nie jest potrzebne, mikrousługi mają jeszcze jedną zaletę: są one modułowe . Oczywiście, monolityczne aplikacje mogą być również modułowe, a ty masz znormalizowaną bazę danych i ... ale w praktyce ściany między modułami są w najlepszym przypadku jak szklane ściany, aw najgorszym - linie na piasku. Mikrousługi są oddzielone litą stalą.
Jeśli system użytkownika dosłownie się zapali, nie wpłynie to w żaden sposób na system ekwipunku. Nie będziesz w stanie wydrukować ładnych raportów o tym, kto co zaopatrzył, ale klienci będą mogli bezpiecznie składać zamówienia, wiedząc, że są tam zapasy.
A ty nie zduplikowane dane w microservices , nie bardziej niż ty w relacyjnej bazie danych (*). W relacyjnej bazie danych możesz wykonać sprzężenie , a odpowiednikiem jest scalenie list w kodzie, jak opisano.
Możesz także dodać widok , odpowiednikiem jest dodanie nowej usługi, która dokonuje scalenia za Ciebie; spowodowałoby to trzy wnioski; jeden do nowej usługi, a następnie ta usługa wykonuje oryginalne dwa. Relacyjne bazy danych mają fantazyjne elementy, które optymalizują widoki, które muszą zostać zaimplementowane na poziomie usługi. Nie dostaniesz go „za darmo”.
Buforowanie różni się od powielania danych tym, że jeśli dwie wartości są niezgodne, wiesz, która z nich jest niepoprawna. Jest często stosowany w mikrousługach, aby zwiększyć dostępność kosztem spójności (twierdzenie CAP). Ponieważ relacyjne bazy danych całkowicie masują dostępność na ołtarzu spójności, jest to w nich mniej powszechne. Powiedziałbym, że nic nie jest związane z mikrousługami, które ułatwiają buforowanie, ale w praktyce buforowanie jest podstawową kwestią i sprawia, że buforowanie jest łatwiejsze w mikrousługach .
(*) Jeśli ma sens powielanie danych w roju mikrousług, prawdopodobnie miałoby to sens w równoważnej relacyjnej bazie danych.
źródło