Jaki jest odpowiedni rozmiar mikrousługi? Często słyszysz coś na skutek, "nie zbyt duży i nie za mały" — i choć z pewnością jest to poprawne, nie jest to bardzo pomocne w praktyce. Jeśli jednak zaczniesz od starannie zaprojektowanego modelu domeny, znacznie łatwiej jest myśleć o mikrousługach.
W tym artykule użyto usługi dostarczania dronów jako działającego przykładu. Więcej informacji na temat scenariusza i odpowiedniej implementacji referencyjnej można znaleźć tutaj.
Z modelu domeny do mikrousług
W poprzednim artykule zdefiniowaliśmy zestaw powiązanych kontekstów dla aplikacji Drone Delivery. Następnie przyjrzeliśmy się bliżej jednemu z tych powiązanych kontekstów, ograniczonemu kontekstowi wysyłki i zidentyfikowaliśmy zestaw jednostek, agregacji i usług domenowych dla tego ograniczonego kontekstu.
Teraz możemy przejść od modelu domeny do projektu aplikacji. Oto metoda, która pozwala tworzyć mikrousługi na podstawie modelu domeny.
Zacznij od ograniczonego kontekstu. Ogólnie rzecz biorąc, funkcjonalność mikrousługi powinna obejmować tylko jeden ograniczony kontekst. Ograniczony kontekst z założenia wyznacza granicę określonego modelu domeny. Jeśli okaże się, że w mikrousłudze mieszają się różne modele domen, może to oznaczać, że trzeba przeprowadzić bardziej precyzyjną analizę domeny.
Następnie przyjrzyj się agregacjom w modelu domeny. Agregacje są często dobrymi kandydatami na mikrousługi. Dobrze zaprojektowana agregacja wykazuje wiele cech dobrze zaprojektowanej mikrousługi, na przykład:
- Agregacja jest oparta na wymaganiach biznesowych, a nie na kwestiach technicznych, takich jak dostęp do danych lub obsługa komunikatów.
- Agregacja powinna mieć wysoką spójność funkcjonalną.
- Agregacja odpowiada trwałej granicy.
- Agregacje powinny być luźno powiązane.
Usługi domenowe są również dobrymi kandydatami na mikrousługi. Usługi domenowe to operacje bezstanowe na wielu agregacjach. Typowym przykładem jest przepływ pracy, który obejmuje kilka mikrousług. Widać to w aplikacji Drone Delivery.
Na koniec weź pod uwagę wymagania niefunkcjonalne. Poszukaj takich czynników, jak wielkość zespołu, typy danych, technologie oraz wymagania dotyczące skalowalności, dostępności i zabezpieczeń. Czynniki te mogą sugerować dalsze rozdzielenie mikrousługi na co najmniej dwie mniejsze usługi lub wykonanie przeciwnej operacji — scalenie kilku mikrousług.
Po zidentyfikowaniu mikrousług w aplikacji zweryfikuj projekt pod kątem następujących kryteriów:
- Każda usługa ma jedną odpowiedzialność.
- Nie ma żadnych rozmów między usługami. Jeśli dzielenie funkcji na dwie usługi powoduje, że są one nadmiernie czatty, może to być objaw, że te funkcje należą do tej samej usługi.
- Każda usługa jest wystarczająco mała, że może zostać utworzona przez mały zespół pracujący niezależnie.
- W kroku blokady nie ma żadnych zależności, które wymagają wdrożenia co najmniej dwóch usług. Zawsze powinno być możliwe wdrożenie usługi bez ponownego wdrażania innych usług.
- Usługi nie są ściśle powiązane i mogą ewoluować niezależnie.
- Granice usługi nie spowodują problemów ze spójnością danych ani integralnością. Czasami ważne jest, aby zachować spójność danych, umieszczając funkcje w jednej mikrousłudze. To powiedzmy, należy rozważyć, czy naprawdę potrzebujesz silnej spójności. Istnieją strategie rozwiązywania problemów ze spójnością ostateczną w systemie rozproszonym, a korzyści wynikające z dekompozycji usług często przewyższają wyzwania związane z zarządzaniem spójnością ostateczną.
Przede wszystkim należy zachować pragmatyczne podejście, pamiętając, że projektowanie oparte na domenach jest procesem iteracyjnym. W przypadku wątpliwości należy zacząć od bardziej „gruboziarnistych” mikrousług. Dzielenie mikrousługi na dwie mniejsze usługi jest łatwiejsze niż refaktoryzacja funkcjonalności na wielu istniejących mikrousługach.
Przykład: Definiowanie mikrousług dla aplikacji Drone Delivery
Przypomnij sobie, że zespół programistyczny zidentyfikował cztery agregacje — dostarczanie, pakiet, dron i konto — oraz dwie usługi domenowe, Harmonogram i Nadzorca.
Dostarczanie i pakowanie są oczywistymi kandydatami do mikrousług. Harmonogram i nadzorca koordynują działania wykonywane przez inne mikrousługi, dlatego warto zaimplementować te usługi domeny jako mikrousługi.
Drony i konto są interesujące, ponieważ należą do innych powiązanych kontekstów. Jedną z opcji jest bezpośrednie wywołanie kontekstu drona i konta. Inną opcją jest utworzenie mikrousług drona i konta w kontekście wysyłki. Te mikrousługi pośredniczyły między powiązanymi kontekstami, ujawniając interfejsy API lub schematy danych, które są bardziej odpowiednie dla kontekstu wysyłki.
Szczegóły kontekstów związanych z dronem i kontem wykraczają poza zakres tych wskazówek, dlatego utworzyliśmy dla nich makiety usług w naszej implementacji referencyjnej. Oto jednak kilka czynników, które należy wziąć pod uwagę w tej sytuacji:
Jakie jest obciążenie sieciowe wywoływania bezpośrednio w innym powiązanym kontekście?
Czy schemat danych dla innego ograniczonego kontekstu jest odpowiedni dla tego kontekstu, czy lepiej mieć schemat dostosowany do tego ograniczonego kontekstu?
Czy drugi ograniczony kontekst jest starszym systemem? Jeśli tak, możesz utworzyć usługę, która działa jako warstwa antykorupcyjna do tłumaczenia między starszym systemem a nowoczesną aplikacją.
Jaka jest struktura zespołu? Czy łatwo komunikować się z zespołem odpowiedzialnym za inny ograniczony kontekst? Jeśli tak nie jest, utworzenie usługi, która pośredniczy między dwoma kontekstami, może pomóc w ograniczeniu kosztów komunikacji między zespołami.
Do tej pory nie rozważaliśmy żadnych wymagań niefunkcjonalnych. Myśląc o wymaganiach dotyczących przepływności aplikacji, zespół deweloperów postanowił utworzyć oddzielną mikrousługę pozyskiwania, która jest odpowiedzialna za pozyskiwanie żądań klientów. Ta mikrousługa implementuje bilansowanie obciążenia przez umieszczenie żądań przychodzących w buforze na potrzeby przetwarzania. Harmonogram odczytuje żądania z buforu i wykonuje przepływ pracy.
Wymagania niefunkcjonalne doprowadziły zespół do utworzenia jednej dodatkowej usługi. Wszystkie usługi do tej pory były o procesie planowania i dostarczania pakietów w czasie rzeczywistym. Jednak system musi również przechowywać historię każdego dostarczania w długoterminowym magazynie na potrzeby analizy danych. Zespół rozważał podjęcie tej odpowiedzialności za usługę dostarczania. Jednak wymagania dotyczące magazynu danych są zupełnie inne w przypadku analizy historycznej i operacji w locie (zobacz Zagadnienia dotyczące danych). W związku z tym zespół zdecydował się utworzyć oddzielną usługę Historia dostarczania, która będzie nasłuchiwać zdarzeń DeliveryTracking z usługi Dostarczania i zapisywać zdarzenia w magazynie długoterminowym.
Na poniższym diagramie przedstawiono projekt w tym momencie:
Pobierz plik programu Visio z tą architekturą.
Następne kroki
W tym momencie należy jasno zrozumieć przeznaczenie i funkcjonalność każdej mikrousługi w projekcie. Teraz możesz zaprojektować system.