Mój scenariusz jest następujący.
Projektuję system zaprojektowany do odbierania danych z różnego rodzaju czujników, a następnie ich konwersji, a następnie przechowywania w celu późniejszego wykorzystania przez różne usługi front-end i analityczne.
Staram się zaprojektować każdą usługę tak, aby była jak najbardziej niezależna, ale mam pewne problemy. Zespół zdecydował się na DTO, którego chcielibyśmy użyć. Usługi skierowane na zewnątrz (odbiorcy danych z czujników) otrzymają dane na swój unikalny sposób, a następnie przekonwertują je na obiekt JSON (DTO) i wyślą do brokera komunikatów. Konsumenci wiadomości będą wtedy dokładnie wiedzieć, jak odczytać komunikaty danych czujnika.
Problem polega na tym, że używam tego samego DTO w kilku różnych usługach. Aktualizacja musi zostać wdrożona w wielu lokalizacjach. Oczywiście zaprojektowaliśmy to w taki sposób, że kilka dodatkowych lub brakujących pól w DTO tutaj i nie ma większego problemu, dopóki usługi nie zostaną zaktualizowane, ale wciąż mnie to denerwuje i sprawia, że czuję się jakbym popełniać błąd. Może łatwo przerodzić się w ból głowy.
Czy zamierzam źle zaprojektować system? Jeśli nie, jakie są sposoby na to, a przynajmniej na złagodzenie moich obaw?
proto
plik gRPC lubavro
schemat dla Kafki i wygenerować DTO w obu usługach, ale nie udostępniłbym wspólnej biblioteki między dwoma projektami.Odpowiedzi:
Moja rada? Nie udostępniaj tych DTO między aplikacjami w jakiejkolwiek bibliotece. A przynajmniej nie rób tego teraz.
Wiem, wydaje się bardzo sprzeczna z intuicją. Kopiujesz kod, prawda? Ale to nie jest reguła biznesowa, więc możesz być bardziej elastyczny.
Usługa wysyłająca DTO musi być sztywna w umowie dotyczącej wiadomości, podobnie jak Rest API. Usługa nie może zmienić DTO w sposób, który mógłby zepsuć inne usługi, które już wykorzystują informacje z DTO.
Po dodaniu nowego pola do DTO aktualizujesz tylko inne usługi korzystające z tego DTO, jeśli potrzebują nowego pola. W przeciwnym razie zapomnij o tym. Używając JSON jako typu zawartości, możesz elastycznie tworzyć i wysyłać nowe atrybuty bez zepsucia kodu usług, które nie mapują tych nowych pól w jego rzeczywistych wersjach DTO.
Ale jeśli ta sytuacja naprawdę Cię niepokoi, możesz przestrzegać Reguły Trzech :
Spróbuj więc poczekać trochę dłużej, zanim udostępnisz to DTO między usługami.
źródło
Jeśli chodzi o Microservices, cykle rozwoju usług również powinny być niezależne. *
Różne zespoły SLDC i różne zespoły programistów
w prawdziwym systemie MS może być kilka zespołów zaangażowanych w rozwój ekosystemu, z których każdy odpowiada za jedną lub więcej usług. Z kolei zespoły te mogą znajdować się w różnych biurach, miastach, krajach, planach… Być może nawet się nie znają, co bardzo utrudnia dzielenie się wiedzą lub kodem (jeśli to możliwe). Ale może to być bardzo wygodne, ponieważ wspólny kod oznacza również rodzaj rozumowania dzielenia się i ważne jest, aby pamiętać, że cokolwiek ma sens dla konkretnego zespołu, nie musi robić tego dla innego zespołu. Na przykład, biorąc pod uwagę klienta DTO , może być inaczej w zależności od usługi w grze, ponieważ klienci są interpretowani (lub widziani) inaczej niż każda usługa.
Różne potrzeby, różne technologie
Izolowane SLDC pozwalają również zespołom wybrać stos, który najlepiej odpowiada ich potrzebom. Nałożenie DTO zaimplementowanych w określonej technologii ogranicza możliwości wyboru zespołów.
DTO nie są ani zasadami biznesowymi, ani umowami o świadczenie usług
Czym naprawdę są DTO? Proste obiekty bez innego celu niż przenoszenie danych z jednej strony na drugą. Torby z getterami i seterami. Nie jest to „wiedza”, którą warto ponownie wykorzystać, ponieważ w ogóle nie ma wiedzy. Ich zmienność czyni ich również złymi kandydatami do połączenia.
W przeciwieństwie do tego, co stwierdził Dherik, usługa musi mieć możliwość zmiany DTO bez konieczności dokonywania zmian w innych usługach w tym samym czasie. Usługi powinny być tolerancyjnymi czytelnikami, tolerancyjnymi pisarzami i odpornymi na błędy . W przeciwnym razie powodują sprzężenie w taki sposób, że architektura usługi nie ma sensu. Jeszcze raz, w przeciwieństwie do odpowiedzi Dherika, jeśli trzy usługi potrzebują dokładnie tych samych DTO, prawdopodobnie coś poszło nie tak podczas rozkładu usług.
Różny biznes, różne interpretacje
Chociaż mogą istnieć (i będą) przekrojowe koncepcje między usługami, nie oznacza to, że musimy narzucić model kanoniczny, aby zmusić wszystkie usługi do interpretowania ich w ten sam sposób.
Studium przypadku
Powiedzmy, że nasza firma ma trzy działy: obsługi klienta , sprzedaży i wysyłki . Powiedz, że każda z tych wersji udostępnia jedną lub więcej usług.
Obsługa klienta, ze względu na język swojej domeny , wdraża usługi wokół koncepcji klientów, gdzie klientami są osoby . Na przykład klienci są modelowani jako imię , nazwisko , wiek , płeć , adres e-mail , telefon itp.
Powiedzmy teraz, że sprzedaż i wysyłka modelują również swoje usługi zgodnie z ich językami domen. W tych językach pojawia się również klient koncepcyjny, ale z subtelną różnicą. Dla nich klienci nie są (koniecznie) osobami . Do sprzedaży , klienci są numer dokumentu karty kredytowej i adres rozliczeniowy , o wysyłce do pełnej nazwy i adresu wysyłki za.
Jeśli zmusimy sprzedaży i wysyłki do przyjęcia kanoniczny model danych Obsługa klienta , jesteśmy zmuszając je do czynienia z niepotrzebnych danych, które może skończyć się wprowadzenie niepotrzebnej złożoności jeśli muszą utrzymać całą reprezentację i utrzymać klienta danych w synchronizacji z obsługą klienta .
Powiązane linki
* Oto, na czym polega siła tej architektury
źródło
Powinieneś publikować wydarzenia . Zdarzenia to pewien rodzaj komunikatów, które stanowią solidny fakt na temat czegoś, co wydarzyło się w określonym momencie.
Każda usługa powinna mieć bardzo dobrze określoną odpowiedzialność i powinna być odpowiedzialna za publikowanie wydarzeń związanych z tą odpowiedzialnością.
Ponadto chcesz, aby Twoje wydarzenia reprezentowały wydarzenia związane z biznesem, a nie wydarzenia techniczne. Np. Wolę
OrderCancelled
wydarzenie odOrderUpdated
zstatus: "CANCELLED"
.W ten sposób, gdy usługa musi zareagować na anulowane zamówienie, musi po prostu wysłuchać określonego rodzaju wiadomości, która przenosi tylko dane istotne dla tego zdarzenia. Np.
OrderCancelled
Prawdopodobnie potrzebuje tylkoorder_id
. Jakakolwiek usługa, która musi na to zareagować, zapisała już wszystko, co musi wiedzieć o zamówieniu we własnym magazynie danych.Ale jeśli usługa miałaby tylko
OrderUpdated
zdarzenia do wysłuchania, musiałaby zinterpretować przebieg zdarzeń, a teraz była zależna od zamówienia dostawy, aby mogła zostać poprawnie zakończona po anulowaniu zamówienia.W twoim przypadku, jednak, jak Twój publikujemy dane czujnika, to może mieć sens mieć usługę, słuchać wydarzeń i opublikować nowy strumień zdarzeń „biznes”, na przykład
TemperatureThresholdExceeded
,TemperatureStabilised
.I uważaj na tworzenie zbyt wielu mikrousług. Mikrousługi mogą być świetnym sposobem na enkapsulowanie złożoności, ale jeśli nie odkryjesz odpowiednich granic usług, twoja złożoność polega na integracji usług. I to jest koszmar do utrzymania.
Lepiej mieć za mało, za dużych usług, niż mieć za dużo, za małych usług.
źródło