Konteneryzowane mikrousługi
Napiwek
Ta zawartość jest fragmentem książki eBook, wzorców aplikacji dla przedsiębiorstw przy użyciu platformy .NET, dostępnej na platformie .NET MAUIDocs lub jako bezpłatnego pliku PDF do pobrania, który można odczytać w trybie offline.
Tworzenie aplikacji klienckich serwerów spowodowało skupienie się na tworzeniu aplikacji warstwowych korzystających z określonych technologii w każdej warstwie. Takie aplikacje są często określane jako monolityczne i są pakowane na sprzęt wstępnie skalowany pod kątem obciążeń szczytowych. Główne wady tego podejścia programistycznego to ścisłe sprzęganie między składnikami w każdej warstwie, że poszczególne składniki nie mogą być łatwo skalowane i koszt testowania. Prosta aktualizacja może mieć nieprzewidziany wpływ na pozostałą część warstwy, więc zmiana składnika aplikacji wymaga ponownego przetestowania i ponownego wdrożenia całej warstwy.
Szczególnie dotyczy to tego, że w wieku chmury poszczególne składniki nie mogą być łatwo skalowane. Aplikacja monolityczna zawiera funkcje specyficzne dla domeny i jest zwykle podzielona przez warstwy funkcjonalne, takie jak fronton, logika biznesowa i magazyn danych. Na poniższym obrazie pokazano, że aplikacja monolityczna jest skalowana przez sklonowanie całej aplikacji na wiele maszyn.
Mikrousługi
Mikrousługi oferują inne podejście do tworzenia i wdrażania aplikacji, czyli podejścia odpowiedniego do wymagań dotyczących elastyczności, skalowania i niezawodności nowoczesnych aplikacji w chmurze. Aplikacja mikrousług jest podzielona na niezależne składniki, które współpracują ze sobą w celu zapewnienia ogólnej funkcjonalności aplikacji. Termin mikrousługi podkreśla, że aplikacje powinny składać się z usług wystarczająco małych, aby odzwierciedlały konkretne obawy, więc każda mikrousługa implementuje jedną funkcję. Ponadto każda mikrousługa ma dobrze zdefiniowane kontrakty, z którymi inne mikrousługi komunikują się i udostępniają dane. Typowe przykłady mikrousług obejmują koszyki zakupów, przetwarzanie spisu, podsystemy zakupów i przetwarzanie płatności.
Mikrousługi mogą być skalowane niezależnie w porównaniu z gigantycznymi aplikacjami monolitycznymi, które skalują się razem. Oznacza to, że określony obszar funkcjonalny, który wymaga większej mocy obliczeniowej lub przepustowości sieci do obsługi zapotrzebowania, można skalować, a nie niepotrzebnie skalować w poziomie inne obszary aplikacji. Na poniższej ilustracji przedstawiono to podejście, w którym mikrousługi są wdrażane i skalowane niezależnie, tworząc wystąpienia usług na maszynach.
Skalowanie mikrousług w poziomie może być niemal natychmiastowe, dzięki czemu aplikacja może dostosować się do zmieniających się obciążeń. Na przykład pojedyncza mikrousługa w funkcji internetowej aplikacji może być jedyną mikrousługą, która musi być skalowana w poziomie w celu obsługi dodatkowego ruchu przychodzącego.
Klasycznym modelem skalowalności aplikacji jest posiadanie warstwy bezstanowej o zrównoważonym obciążeniu z udostępnionym zewnętrznym magazynem danych do przechowywania trwałych danych. Mikrousługi stanowe zarządzają własnymi trwałymi danymi, zwykle przechowując je lokalnie na serwerach, na których są umieszczone, aby uniknąć obciążenia związanego z dostępem do sieci i złożonością operacji obejmujących wiele usług. Umożliwia to najszybsze przetwarzanie danych i może wyeliminować konieczność buforowania systemów. Ponadto skalowalne mikrousługi stanowe zwykle partycjonują dane między wystąpieniami, aby zarządzać rozmiarem danych i przesyłać przepływność, poza którą może obsługiwać pojedynczy serwer.
Mikrousługi obsługują również niezależne aktualizacje. To luźne sprzężenie między mikrousługami zapewnia szybką i niezawodną ewolucję aplikacji. Ich niezależny, rozproszony charakter ułatwia stopniowe aktualizowanie, w którym tylko podzbiór wystąpień pojedynczej mikrousługi będzie aktualizowany w danym momencie. W związku z tym w przypadku wykrycia problemu można wycofać aktualizację usterek, zanim wszystkie wystąpienia zostaną zaktualizowane przy użyciu wadliwego kodu lub konfiguracji. Podobnie mikrousługi zwykle używają przechowywania wersji schematu, dzięki czemu klienci widzą spójną wersję po zastosowaniu aktualizacji, niezależnie od tego, z którym wystąpieniem mikrousługi jest komunikowane.
W związku z tym aplikacje mikrousług mają wiele zalet w przypadku aplikacji monolitycznych:
- Każda mikrousługa jest stosunkowo mała, łatwa do zarządzania i rozwoju.
- Każdą mikrousługę można opracowywać i wdrażać niezależnie od innych usług.
- Każdą mikrousługę można skalować w poziomie niezależnie. Na przykład usługa katalogu lub usługa koszyka zakupów może wymagać skalowania w poziomie więcej niż usługa zamawiania. W związku z tym wynikowa infrastruktura będzie wydajniej wykorzystywać zasoby podczas skalowania w górę.
- Każda mikrousługa izoluje wszelkie problemy. Jeśli na przykład występuje problem w usłudze, ma to wpływ tylko na tę usługę. Inne usługi mogą nadal obsługiwać żądania.
- Każda mikrousługa może korzystać z najnowszych technologii. Ponieważ mikrousługi są autonomiczne i uruchamiane obok siebie, mogą być używane najnowsze technologie i struktury, zamiast wymuszać korzystanie ze starszej struktury, która może być używana przez aplikację monolityczną.
Jednak rozwiązanie oparte na mikrousługach ma również potencjalne wady:
- Wybór sposobu partycjonowania aplikacji na mikrousługi może być trudny, ponieważ każda mikrousługa musi być całkowicie autonomiczna, kompleksowa, w tym odpowiedzialność za źródła danych.
- Deweloperzy muszą zaimplementować komunikację między usługami, co zwiększa złożoność i opóźnienie aplikacji.
- Transakcje niepodzielne między wieloma mikrousługami zwykle nie są możliwe. W związku z tym wymagania biznesowe muszą obejmować spójność ostateczną między mikrousługami.
- W środowisku produkcyjnym istnieje złożoność operacyjna wdrażania systemu z naruszonymi zabezpieczeniami wielu niezależnych usług i zarządzania nim.
- Bezpośrednia komunikacja między mikrousługami może utrudnić refaktoryzację kontraktów mikrousług. Na przykład w czasie może być konieczne podzielenie systemu na usługi. Pojedyncza usługa może być podzielona na co najmniej dwie usługi, a dwie usługi mogą zostać scalone. Gdy klienci komunikują się bezpośrednio z mikrousługami, ta refaktoryzacja może przerwać zgodność z aplikacjami klienckimi.
Konteneryzacja
Konteneryzacja to podejście do tworzenia oprogramowania, w którym aplikacja i jej zestaw wersji zależności oraz konfiguracja środowiska abstrakcyjna jako pliki manifestu wdrożenia są pakowane razem jako obraz kontenera, testowane jako jednostka i wdrażane w systemie operacyjnym hosta.
Kontener jest izolowanym, kontrolowanym zasobem i przenośnym środowiskiem operacyjnym, w którym aplikacja może działać bez dotykania zasobów innych kontenerów lub hosta. W związku z tym kontener wygląda i działa jak nowo zainstalowany komputer fizyczny lub maszyna wirtualna.
Istnieje wiele podobieństw między kontenerami i maszynami wirtualnymi, jak pokazano poniżej.
Kontener uruchamia system operacyjny, ma system plików i można uzyskać do niego dostęp za pośrednictwem sieci tak, jakby była to maszyna fizyczna lub wirtualna. Jednak technologia i pojęcia używane przez kontenery różnią się zupełnie od maszyn wirtualnych. Maszyny wirtualne obejmują aplikacje, wymagane zależności i pełny system operacyjny gościa. Kontenery obejmują aplikację i jej zależności, ale współużytkować system operacyjny z innymi kontenerami, uruchomione jako izolowane procesy w systemie operacyjnym hosta (oprócz kontenerów funkcji Hyper-V, które działają wewnątrz specjalnej maszyny wirtualnej na kontener). W związku z tym kontenery współdzielą zasoby i zwykle wymagają mniejszej ilości zasobów niż maszyny wirtualne.
Zaletą podejścia do programowania i wdrażania zorientowanego na kontenery jest wyeliminowanie większości problemów wynikających z niespójnych konfiguracji środowiska i problemów, które są z nimi związane. Ponadto kontenery umożliwiają szybkie skalowanie aplikacji w górę przez tworzenie nowych kontenerów zgodnie z potrzebami.
Kluczowe pojęcia dotyczące tworzenia kontenerów i pracy z nimi są następujące:
Koncepcja | opis |
---|---|
Host kontenera | Maszyna fizyczna lub wirtualna skonfigurowana do hostowania kontenerów. Host kontenera uruchomi co najmniej jeden kontener. |
Obraz kontenera | Obraz składa się z połączenia warstwowych systemów plików skumulowanych nawzajem i jest podstawą kontenera. Obraz nie ma stanu i nigdy nie zmienia się, ponieważ jest wdrażany w różnych środowiskach. |
Kontener | Kontener to wystąpienie środowiska uruchomieniowego obrazu. |
Obraz systemu operacyjnego kontenera | Kontenery są wdrażane z obrazów. Obraz systemu operacyjnego kontenera jest pierwszą warstwą w potencjalnie wielu warstwach obrazów tworzących kontener. System operacyjny kontenera jest niezmienny i nie można go modyfikować. |
Repozytorium kontenerów | Za każdym razem, gdy obraz kontenera jest tworzony, obraz i jego zależności są przechowywane w repozytorium lokalnym. Te obrazy można używać wiele razy na hoście kontenera. Obrazy kontenerów mogą być również przechowywane w rejestrze publicznym lub prywatnym, takim jak Docker Hub, dzięki czemu mogą być używane na różnych hostach kontenerów. |
Przedsiębiorstwa coraz częściej wdrażają kontenery podczas implementowania aplikacji opartych na mikrousługach, a platforma Docker stała się standardową implementacją kontenerów, która została przyjęta przez większość platform oprogramowania i dostawców usług w chmurze.
Aplikacja referencyjna eShop używa platformy Docker do hostowania czterech konteneryzowanych mikrousług zaplecza, jak pokazano na poniższym diagramie.
Architektura usług zaplecza w aplikacji referencyjnej jest rozłożona na wiele autonomicznych systemów podrzędnych w postaci współpracujących mikrousług i kontenerów. Każda mikrousługa oferuje jeden obszar funkcjonalności: usługę tożsamości, usługę katalogu, usługę zamawiania i usługę koszyka.
Każda mikrousługa ma własną bazę danych, umożliwiając jej całkowite oddzielenie od innych mikrousług. W razie potrzeby spójność między bazami danych z różnych mikrousług jest osiągana przy użyciu zdarzeń na poziomie aplikacji. Aby uzyskać więcej informacji, zobacz Komunikacja między mikrousługami.
Komunikacja między klientem a mikrousługami
Aplikacja wieloplatformowa eShop komunikuje się z konteneryzowanymi mikrousługami zaplecza przy użyciu bezpośredniej komunikacji między klientami i mikrousługami , jak pokazano poniżej.
Dzięki bezpośredniej komunikacji między klientem a mikrousługą aplikacja wieloplatformowa wysyła żądania do każdej mikrousługi bezpośrednio za pośrednictwem publicznego punktu końcowego z innym portem TCP na mikrousługę. W środowisku produkcyjnym punkt końcowy zazwyczaj mapuje się na moduł równoważenia obciążenia mikrousługi, który dystrybuuje żądania między dostępne wystąpienia.
Napiwek
Rozważ użycie komunikacji bramy interfejsu API.
Bezpośrednia komunikacja między klientem a mikrousługą może mieć wady podczas kompilowania dużej i złożonej aplikacji opartej na mikrousługach, ale jest to bardziej niż odpowiednie dla małej aplikacji. Rozważ użycie komunikacji bramy interfejsu API podczas projektowania dużej aplikacji opartej na mikrousługach z dziesiątkami mikrousług.
Komunikacja między mikrousługami
Aplikacja oparta na mikrousługach jest systemem rozproszonym, potencjalnie działającym na wielu maszynach. Każde wystąpienie usługi jest zazwyczaj procesem. W związku z tym usługi muszą korzystać z protokołu komunikacyjnego między procesami, takiego jak HTTP, TCP, Advanced Message Queuing Protocol (AMQP) lub protokoły binarne, w zależności od charakteru każdej usługi.
Dwie typowe podejścia do komunikacji między mikrousługami to komunikacja REST oparta na protokole HTTP podczas wykonywania zapytań dotyczących danych oraz uproszczone komunikaty asynchroniczne podczas komunikowania aktualizacji w wielu mikrousługach.
Asynchroniczna komunikacja oparta na zdarzeniach oparta na komunikatach ma kluczowe znaczenie podczas propagacji zmian w wielu mikrousługach. Dzięki temu mikrousługa publikuje zdarzenie, gdy wystąpi coś, co można zauważyć, na przykład w przypadku aktualizacji jednostki biznesowej. Inne mikrousługi subskrybują te zdarzenia. Następnie, gdy mikrousługa odbiera zdarzenie, aktualizuje własne jednostki biznesowe, co z kolei może prowadzić do opublikowania większej liczby zdarzeń. Ta funkcja publikowania-subskrybowania jest zwykle osiągana za pomocą magistrali zdarzeń.
Magistrala zdarzeń umożliwia komunikację między mikrousługami typu publish-subscribe bez konieczności jawnego informowania składników o sobie, jak pokazano poniżej.
Z perspektywy aplikacji magistrala zdarzeń jest po prostu kanałem publikowania-subskrybowania udostępnianym za pośrednictwem interfejsu. Jednak sposób implementacji magistrali zdarzeń może się różnić. Na przykład implementacja magistrali zdarzeń może używać bibliotek RabbitMQ, Azure Service Bus lub innych magistrali usług, takich jak NServiceBus i MassTransit. Na poniższym diagramie przedstawiono sposób użycia magistrali zdarzeń w aplikacji referencyjnej eShop.
Magistrala zdarzeń eShop zaimplementowana przy użyciu biblioteki RabbitMQ zapewnia funkcję "jeden do wielu" asynchronicznego publikowania i subskrybowania. Oznacza to, że po opublikowaniu zdarzenia może być wielu subskrybentów nasłuchujących tego samego zdarzenia. Na poniższym diagramie przedstawiono tę relację.
To podejście komunikacyjne jeden do wielu używa zdarzeń do implementowania transakcji biznesowych obejmujących wiele usług, zapewniając spójność ostateczną między usługami. Ostateczna transakcja składa się z serii kroków rozproszonych. W związku z tym gdy mikrousługa profilu użytkownika otrzymuje polecenie UpdateUser, aktualizuje szczegóły użytkownika w bazie danych i publikuje zdarzenie UserUpdated w magistrali zdarzeń. Zarówno mikrousługi koszyka, jak i mikrousługi zamawiania zasubskrybowały odbieranie tego zdarzenia, a w odpowiedzi aktualizują informacje o nabywcy w odpowiednich bazach danych.
Podsumowanie
Mikrousługi oferują podejście do tworzenia i wdrażania aplikacji, które jest odpowiednie dla wymagań dotyczących elastyczności, skalowania i niezawodności nowoczesnych aplikacji w chmurze. Jedną z głównych zalet mikrousług jest możliwość niezależnego skalowania ich w poziomie, co oznacza, że można skalować określony obszar funkcjonalny, który wymaga większej mocy obliczeniowej lub przepustowości sieci w celu obsługi zapotrzebowania bez niepotrzebnego skalowania obszarów aplikacji, które nie mają zwiększonego zapotrzebowania.
Kontener to izolowane, kontrolowane przez zasoby i przenośne środowisko operacyjne, w którym aplikacja może działać bez dotykania zasobów innych kontenerów lub hosta. Przedsiębiorstwa coraz częściej wdrażają kontenery podczas implementowania aplikacji opartych na mikrousługach, a platforma Docker stała się standardową implementacją kontenerów, którą przyjęła większość platform oprogramowania i dostawców usług w chmurze.