Mikroserwisy w akcji. Отсутствует
odpowiedzialne za koordynację działań w systemie jest zasadniczą różnicą między tym podejściem a tradycyjnymi architekturami zorientowanymi na usługi (SOA). Tego typu systemy często wykorzystywały korporacyjne magistrale usług (ESB) lub bardziej złożone standardy orkiestracji, aby uzewnętrzniać komunikację i proces orkiestracji z samych aplikacji. W tym modelu usługi często nie były spójne, ponieważ logika biznesowa była dodawana do magistrali usług, a nie do samych usług.
Warto się zastanowić, w jaki sposób wydzielanie funkcjonalności w internetowym systemie inwestycyjnym pozwala na większą elastyczność w obliczu zmieniających się wymagań. Wyobraźmy sobie, że musimy zmienić sposób naliczania opłat. Możemy wprowadzić i wydać te zmiany w usłudze fees bez żadnych zmian w usługach wyższego lub niższego poziomu. Albo przyjmijmy zupełnie nowy wymóg – musimy powiadomić zespół ds. ryzyka, gdy jest składane zamówienie niepasujące do typowych schematów handlu. Łatwo byłoby zbudować nowy mikroserwis, aby wykonać tę operację, bazując na zdarzeniu wywołanym przez usługę orders bez zmiany reszty systemu.
Rysunek 1.1. Przepływ komunikacji przez mikroserwisy w aplikacji, która pozwala użytkownikom sprzedawać papiery wartościowe
1.1.1. Skalowanie przez dekompozycję
Możemy się także zastanowić, w jaki sposób mikroserwisy pozwalają na skalowanie aplikacji. W The Art of Scalability Abbott i Fisher definiują trzy wymiary skalowania jako kostkę (rys. 1.2).
Aplikacje monolityczne są zazwyczaj skalowane przez horyzontalne duplikowanie – wdrażanie wielu identycznych wystąpień aplikacji. Jest to również znane jako skalowanie cookiem cutter lub skalowanie w osi X. Aplikacje mikroserwisowe są przykładem skalowania w osi Y, w którym jest wykonywana dekompozycja systemu, aby sprostać unikalnym potrzebom skalowania różnych funkcjonalności.
UWAGA Oś Z odnosi się do poziomego partycjonowania danych – fragmentowania. Można zastosować fragmentowanie do obu podejść, mikroserwisów lub aplikacji monolitycznych, ale nie będziemy się tym zajmować w tej książce.
Rysunek 1.2. Trzy wymiary skalowania aplikacji
Ponownie jako przykładowi przyjrzyjmy się narzędziu inwestycyjnemu o następujących cechach:
■ prognozy finansowe mogą być złożone obliczeniowo i występować rzadko;
■ rachunki inwestycyjne mogą być regulowane przez skomplikowane przepisy prawne i biznesowe;
■ handel na giełdzie może się odbywać w bardzo dużych ilościach, a jednocześnie wymagać minimalizowania opóźnień.
Jeśli tworzymy funkcjonalności jako mikroserwisy, które spełniają pewne wymagania, możemy wybrać idealne narzędzia do rozwiązania danego problemu, zamiast próbować dopasować kwadratowe kołki do okrągłych otworów. Ponadto, autonomia i niezależność wdrażania oznacza, że możemy zarządzać potrzebnymi wymaganiami mikroserwisów osobno. Co ciekawe, oznacza to naturalny sposób na ograniczenie niepowodzeń – jeśli nasza usługa prognozowania finansowego nie zadziała, to jest mało prawdopodobne, aby ta awaria kaskadowo przeniosła się do obrotu na giełdzie lub usług obsługi rachunku inwestycyjnego.
Aplikacje mikroserwisowe mają kilka interesujących właściwości technicznych:
■ budowanie usług odpowiadających pojedynczym zdolnościom stawia naturalne granice co do wielkości i odpowiedzialności;
■ autonomia pozwala niezależnie rozwijać, wdrażać i skalować usługi.
1.1.2. Kluczowe zasady
Rozwój mikroserwisów jest wspierany przez pięć zasad kulturowych i architektonicznych:
■ autonomię,
■ odporność,
■ przejrzystość,
■ automatyzację,
■ ukierunkowanie.
Zasady te powinny wpływać na decyzje techniczne i organizacyjne podczas budowania i uruchamiania aplikacji mikroserwisowych. Przeanalizujmy każdą z nich.
AUTONOMIA
Ustaliliśmy, że mikroserwisy są autonomiczne – każda usługa działa i zmienia się niezależnie od innych. W celu zapewnienia autonomii nasze usługi musimy zaprojektować tak, aby były:
■ luźno powiązane – dzięki interakcji za pośrednictwem jasno zdefiniowanych interfejsów lub generowanych zdarzeń każdy mikroserwis może pozostawać niezależny od wewnętrznej implementacji współpracowników; na przykład usługa obsługi zleceń, którą wprowadziliśmy wcześniej, nie powinna być świadoma sposobu implementacji usługi transakcji na rachunku – zilustrowano to na rysunku 1.3;
■ niezależnie wdrażane – usługi będą tworzone równolegle, często przez wiele zespołów, gdyż konieczność ich łącznego wydawania doprowadziłaby do ryzykownych i niepewnych wdrożeń; najlepsze jest korzystanie z mniejszych usług, aby umożliwić ich szybkie, częste i małe wydania.
Autonomia jest także kulturą. Ważne jest, aby delegować odpowiedzialność i własność usług do zespołów odpowiedzialnych za wpływ na biznes. Jak ustaliliśmy, projekt organizacyjny ma wpływ na projektowanie systemu. Przejrzystość usług pozwala zespołom na iteracyjne budowanie i podejmowanie decyzji, oparte na lokalnym kontekście i celu. Ponadto, taki model jest idealny do promowania kompleksowej własności, gdy zespół jest odpowiedzialny za usługę zarówno w okresie rozwoju, jak i na produkcji.
Rysunek 1.3. Można luźno wiązać usługi komunikujące się za pomocą określonych kontraktów i ukrywające szczegóły implementacji
UWAGA W rozdziale 13 omówimy rozwijanie odpowiedzialnych i autonomicznych zespołów inżynierskich i pokażemy, dlaczego jest to kluczowe podczas pracy z mikroserwisami.
ODPORNOŚĆ
Mikroserwisy są naturalnym mechanizmem izolowania awarii – jeśli wdrażamy je niezależnie, awaria aplikacji lub infrastruktury może wpłynąć tylko na część naszego systemu. Ponadto, możliwość wdrażania mniejszych fragmentów funkcjonalności powinna pomóc w stopniowej zmianie systemu, nie narażać na ryzykowny Wielki Wybuch związany z nową funkcjonalnością.
Ponownie rozważmy narzędzie inwestycyjne. Jeśli usługa obsługi giełdy jest niedostępna, złożenie zlecenia na giełdzie nie będzie możliwe. Użytkownik może jednak zażądać złożenia zlecenia, a usługa może je odebrać później, gdy będzie dostępna podrzędna funkcjonalność.
Mimo że dzielenie aplikacji na wiele usług może izolować awarię, to zwiększa także liczbę punktów awarii. Ponadto musimy wziąć pod uwagę, co się stanie, gdy wystąpi awaria, aby zapobiec kaskadzie awarii. W zakresie projektowania obejmuje to zarówno preferowanie asynchronicznej interakcji tam, gdzie jest to możliwe, jak i odpowiednie stosowanie bezpieczników i limitów czasowych, natomiast w zakresie działania – stosowanie sprawdzonych technik ciągłego dostarczania i solidną kontrolę aktywności systemu.
PRZEJRZYSTOŚĆ
Najważniejsze, byśmy wiedzieli, kiedy wystąpiła awaria, a aplikacja mikroserwisowa – w odróżnieniu od jednego systemu – zależy od interakcji i zachowania wielu usług, prawdopodobnie zbudowanych przez różne zespoły. W każdym momencie system