Wzorzec: architektura mikrousług
Kontekst
Tworzysz aplikację korporacyjną po stronie serwera, która musi obsługiwać wielu różnych klientów, w tym przeglądarki stacjonarne, przeglądarki mobilne i natywne aplikacje mobilne. Aplikacja może również udostępniać API do wykorzystania przez osoby trzecie. Może również integrować się z innymi aplikacjami za pośrednictwem usług internetowych lub brokera komunikatów. Aplikacja obsługuje żądania (żądania i komunikaty HTTP), wykonując logikę biznesową; dostęp do bazy danych; wymiana wiadomości z innymi systemami; i zwracając odpowiedź HTML / JSON / XML. Istnieją logiczne komponenty odpowiadające różnym obszarom funkcjonalnym aplikacji.
Problem
Jaka jest architektura wdrażania aplikacji?
Siły
- Istnieje zespół programistów pracujących nad aplikacją
- Nowi członkowie zespołu muszą szybko stać się produktywni
- Aplikacja musi być łatwa do zrozumienia i zmodyfikuj
- Chcesz ćwiczyć ciągłe wdrażanie aplikacji
- Musisz uruchomić wiele instancji aplikacji na wielu maszynach, aby spełnić wymagania dotyczące skalowalności i dostępności.
- Chcesz wykorzystać nowe technologie (frameworki, języki programowania itp.)
Rozwiązanie
Zdefiniuj architekturę, która ustrukturyzuje aplikację jako zestaw luźno powiązanych, usługi współpracujące. To podejście odpowiada osi Y Scale Cube. Każda usługa jest:
- Wysoce konserwowalna i testowalna – umożliwia pid i częste opracowywanie i wdrażanie
- Luźno powiązane z innymi usługami – umożliwia zespołowi niezależną pracę przez większość czasu nad swoimi usługami bez wpływu zmian w innych usługach i bez wpływu na inne usługi
- Możliwość niezależnego wdrażania – umożliwia zespołowi wdrażanie usług bez konieczności koordynacji z innymi zespołami.
- Możliwość tworzenia przez mały zespół – niezbędna do wysokiej produktywności dzięki uniknięciu wysokiego szefa komunikacji dużego zespoły
Usługi komunikują się za pomocą protokołów synchronicznych, takich jak HTTP / REST, lub protokołów asynchronicznych, takich jak AMQP. usługi można opracowywać i wdrażać niezależnie od siebie. każda usługa ma własną bazę danych w celu być oddzielone od innych usług. Spójność danych między usługami jest utrzymywana przy użyciu wzorca Saga
Aby dowiedzieć się więcej o naturze usługi, przeczytaj ten artykuł.
Przykłady
Fikcyjne aplikacje do handlu elektronicznego na
Wyobraźmy sobie, że budujesz aplikację e-commerce, która przyjmuje zamówienia od klientów, weryfikuje zapasy i dostępne kredyty oraz wysyła je. Aplikacja składa się z kilku komponentów, w tym StoreFrontUI, który implementuje interfejs użytkownika , wraz z niektórymi usługami backendu do sprawdzania kredytu, obsługi zapasów i zamówień wysyłkowych. Aplikacja składa się z zestawu usług.
Pokaż kod
Zobacz przykładowe aplikacje opracowane przez Chrisa Richardsona. Te przykłady na Github ilustrują różne aspekty architektury mikrousług.
Wynikowy kontekst
Korzyści
To rozwiązanie ma wiele zalet:
- Umożliwia ciągłe dostarczanie i wdrażanie dużych, złożonych aplikacji.
- Ulepszona łatwość utrzymania – każda usługa jest stosunkowo niewielka, a zatem łatwiejsza do zrozumienia i zmiany
- Lepsza testowalność – usługi są mniejsze i szybsze do testowania
- Lepsze wdrażanie – usługi może być wdrażany niezależnie
- Umożliwia organizowanie prac programistycznych wokół wielu autonomicznych zespołów. Każdy zespół (tzw. Dwie pizze) posiada i jest odpowiedzialny za jedną lub więcej usług. Każdy zespół może opracowywać, testować, wdrażać i skalować swoje usługi niezależnie od wszystkich innych zespołów.
- Każda mikrousługa jest stosunkowo niewielka:
- Łatwiej programista do zrozumienia
- Środowisko IDE jest szybsze, dzięki czemu programiści są bardziej produktywni
- Aplikacja uruchamia się szybciej, co zwiększa produktywność programistów i przyspiesza wdrażanie
- Ulepszona izolacja błędów. Na przykład, jeśli nastąpi wyciek pamięci w jednej usłudze, to wpłynie to tylko na tę usługę, inne usługi będą nadal obsługiwać żądania. Dla porównania, jeden źle działający składnik architektury monolitycznej może spowodować uszkodzenie całego systemu.
- Eliminuje jakiekolwiek długoterminowe zaangażowanie w stos technologii. Podczas opracowywania nowej usługi można wybrać nowy stos technologiczny. Podobnie, wprowadzając poważne zmiany w istniejącej usłudze, można ją przepisać przy użyciu nowego stosu technologii.
Wady
To rozwiązanie ma szereg wad:
- Programiści muszą radzić sobie z dodatkową złożonością tworzenia systemu rozproszonego:
- Programiści muszą zaimplementować mechanizm komunikacji między usługami i poradzić sobie z częściową awarią
- Wdrażanie żądań obejmujących wiele usług jest trudniejsze
- Testowanie interakcji między usługami jest trudniejsze trudne
- Wdrażanie żądań obejmujących wiele usług wymaga starannej koordynacji między zespołami.
- Narzędzia programistyczne / IDE są zorientowane na tworzenie monolitycznych aplikacji i nie zapewniają wyraźnego wsparcia dla tworzenia aplikacji rozproszonych.
- Złożoność wdrażania. W środowisku produkcyjnym występuje także operacyjna złożoność wdrażania systemu składającego się z wielu różnych usług i zarządzania nim.
- Zwiększone zużycie pamięci. Architektura mikrousług zastępuje N monolitycznych instancji aplikacji instancjami usług NxM. Jeśli każda usługa działa w swojej własnej JVM (lub równoważnej), co zwykle jest konieczne do izolowania instancji, wówczas narzut wynosi M razy więcej środowisk wykonawczych JVM. Co więcej, jeśli każda usługa działa na własnej maszynie wirtualnej (np. Instancja EC2), jak ma to miejsce w przypadku Netflix, narzut jest jeszcze wyższy.
Problemy
wiele kwestii, którymi należy się zająć.
Kiedy używać architektury mikrousług?
Jednym z wyzwań związanych z zastosowaniem tego podejścia jest podjęcie decyzji, kiedy warto z niego skorzystać. Podczas tworzenia pierwszej wersji aplikacji, często nie masz problemów, które rozwiązuje takie podejście, ponadto zastosowanie rozbudowanej, rozproszonej architektury spowolni rozwój, co może stanowić poważny problem dla startupów, których największym wyzwaniem jest często szybka ewolucja modelu biznesowego i towarzysząca temu Użycie podziałów osi Y może znacznie utrudnić szybkie iteracje. Jednak później, gdy wyzwaniem jest skalowanie i musisz użyć dekompozycji funkcjonalnej, splątane zależności mogą utrudnić rozłożenie monolitycznej aplikacji na zestaw usług.
Jak zdekomponować aplikację do usług?
Kolejnym wyzwaniem jest podjęcie decyzji, jak podzielić system na mikrousługi. To w dużej mierze sztuka, ale istnieje wiele strategii, które mogą pomóc:
- Dekomponuj według możliwości biznesowych i definiuj usługi odpowiadające możliwościom biznesowym.
- Dekomponuj według poddomeny projektowej opartej na domenie.
- Dekomponuj według czasownika lub przypadku użycia i definiuj usługi odpowiedzialne za określone działania . na przykład a
Shipping Service
, który jest odpowiedzialny za wysyłkę kompletnych zamówień. - Rozłóż według rzeczowników lub zasobów, definiując usługę, która jest odpowiedzialna za wszystkie operacje na obiektach / zasobach danego rodzaj. na przykład
Account Service
, który jest odpowiedzialny za zarządzanie kontami użytkowników.
Idealnie, każda usługa powinna mieć tylko niewielki zakres obowiązków. (Wujek) Bob Martin mówi o projektowaniu klas z wykorzystaniem zasady pojedynczej odpowiedzialności (SRP). SRP definiuje odpowiedzialność klasy jako powód do zmiany i stwierdza, że klasa powinna mieć tylko jeden powód do zmiany. sensowne jest stosowanie SRP do projektowania usług
Inną analogią, która pomaga w projektowaniu usług, jest projektowanie narzędzi uniksowych. Unix zapewnia dużą liczbę narzędzi, takich jak grep, cat i find. Każde narzędzie robi dokładnie jedną rzecz, często wyjątkowo dobrze, i ma być łączony z innymi narzędziami przy użyciu skryptu powłoki do wykonywania złożonych zadań.
Jak zachować spójność danych?
Aby zapewnić luźne powiązanie, każda usługa ma swój własny Utrzymanie spójności danych między usługami jest wyzwaniem, ponieważ transakcje 2-fazowe / rozproszone nie są opcja dla wielu aplikacji.Aplikacja musi zamiast tego używać wzorca Saga.usługa publikuje zdarzenie, gdy zmieniają się jej dane.Inne usługi wykorzystują to zdarzenie i aktualizują swoje dane.Istnieje kilka sposobów niezawodnej aktualizacji danych i publikowania zdarzeń, w tym pozyskiwanie zdarzeń i Śledzenie dzienników transakcji.
Jak wdrażać zapytania?
Kolejnym wyzwaniem jest implementacja zapytań, które muszą pobierać dane należące do wielu usług.
- Interfejs API Wzorce segregacji odpowiedzialności za zapytania dotyczące kompozycji i poleceń (CQRS).
Istnieje wiele wzorców związanych ze wzorcem mikrousług. Architektura monolityczna jest alternatywą dla architektury mikrousług. Inne wzorce dotyczą problemów, które można napotkać podczas stosowania architektury mikrousług.
- Wzorce dekompozycji
- Dekompozycja według możliwości biznesowych
- Dekompozycja według subdomeny
- Wzorzec Database per Service opisuje, jak każda serwis posiada własną bazę danych w celu zapewnienia luźnego powiązania.
- Wzorzec API Gateway określa, w jaki sposób klienci uzyskują dostęp do usług w architekturze mikrousług.
- Wzorce wykrywania po stronie klienta i wykrywania po stronie serwera są używane do kierowania żądań klienta do dostępne wystąpienie usługi w architekturze mikrousług.
- Wzorce obsługi wiadomości i zdalnego wywołania procedur to dwa różne sposoby komunikacji między usługami.
- Wzorce pojedynczej usługi na hosta i wielu usług na hosta są dwie różne strategie wdrażania.
- Przekrojowe wzorce problemów: wzorzec obudowy mikrousług i konfiguracja zewnętrzna
- Wzorce testowania: test komponentów usługi i test kontraktu integracji usług.
- Obwód Breaker
- Access Token
- Wzorce obserwowalności:
- Agregacja logów
- Metryki aplikacji
- Rejestrowanie audytu
- Śledzenie rozproszone
- Śledzenie wyjątków
- Interfejs API sprawdzania stanu
- Wdrażania i zmiany w dzienniku
- Wzorce interfejsu użytkownika:
- Kompozycja fragmentu strony po stronie serwera
- Kompozycja interfejsu użytkownika po stronie klienta
Znane zastosowania
Większość dużych witryn internetowych, w tym Netflix, Amazon i eBay, ewoluowała od architektury monolitycznej do architektury mikrousług.
Netflix, bardzo popularna usługa przesyłania strumieniowego wideo, która jest odpowiedzialna obsługuje do 30% ruchu internetowego, ma architekturę zorientowaną na usługi na dużą skalę i obsługuje ponad miliard wywołań dziennie z ponad 800 różnych typów urządzeń. wywołania usług backendu.
Amazon.com pierwotnie miał architekturę dwuwarstwową. Aby skalować, migrował do architektury zorientowanej na usługi składającej się z setek usług zaplecza. Kilka aplikacji wywołuje te usługi, w tym aplikacje które implementują witrynę Amazon.com i interfejs API usług internetowych. Aplikacja witryny Amazon.com wywołuje 100-150 usług, aby uzyskać rozszerzenie dane, które posłużyły do zbudowania strony internetowej.
Serwis aukcyjny ebay.com również ewoluował z architektury monolitycznej do architektury zorientowanej na usługi. Warstwa aplikacji składa się z wielu niezależnych aplikacji. Każda aplikacja implementuje logikę biznesową dla określonego obszaru funkcji, takiego jak kupowanie lub sprzedawanie. każda aplikacja używa podziałów osi X, a niektóre aplikacje, takie jak wyszukiwanie, używają podziałów osi Z. ebay.com stosuje również kombinację skalowania w stylu X, Y i Z do warstwa bazy danych.
Istnieje wiele innych przykładów firm korzystających z architektury mikrousług.
Chris Richardson ma przykłady aplikacji opartych na mikrousługach.
Zobacz także
Zapoznaj się z moją myślą przewodnią Code Freeze 2018, która stanowi dobre wprowadzenie do architektury mikrousług.