Mikroserwisy – API gateway, czyli drzwi wejściowe do naszego systemu

Zapomnijmy na chwilę o mikroserwisach pomimo, że mowa o nich w tytule. Wyobraźmy sobie serwer udostępniający dane o użytkownikach pewnego portalu społecznościowego. Niech będą to szczegółowe dane takie jak imię, nazwisko, ale i ostatnie aktywności na portalu czy też opublikowane posty. Taki serwer udostępnia pewnie jakieś API do pobierania tych informacji zgromadzonych w bazie danych. Powiedzmy, że mamy metodę GetPerson(), która to wykorzystując warstwę aplikacyjną odpytuje repozytoria o dane osoby z innej tabeli wczytujemy ostatnie aktywności a jeszcze z innej ostatnie posty użytkownika. W tej sytuacji aplikacyjna kliencka odpytuje nasze API, odpowiednio prezentuje dane i mamy to.

(źródło: https://docs.microsoft.com/pl-pl/dotnet/architecture/microservices/architect-microservice-container-applications/direct-client-to-microservice-communication-versus-the-api-gateway-pattern)

Problemy rozproszonej lokalizacji zasobów

Wróćmy do mikroserwisów. Sytuacja nieco komplikuje się, bo dane interesujące aplikacje klienckie są rozsiane po różnych zakamarkach systemu. W ostateczności moglibyśmy w końcu dociec gdzie co jest zlokalizowane, w jakim formacie musimy odpytać dany mikroserwis (albo zmusić wszystkie do wystawiania Rest API itd.), ale rodzi to wiele problemów:

  1. Co z uwierzytelnianiem? Czy każdy mikroserwis musi się tym przejmować?
  2. Jak zminimalizować wpływ zmian w strukturze i funkcjonalności mikroserwisów na działanie klientów?
  3. Co ze skalowaniem? Co jeżeli zwiększamy liczbę instancji danego serwisu? Kto decyduje o adresie docelowym zapytania?
  4. Załóżmy, że zmieniamy odpowiedzialności mikroserwisów, wprowadzamy nowe, usuwamy stare. Jakkolwiek zmieniamy wewnętrzną strukturę systemu. Jak wyeliminować zmiany po stronie klientów API?

Rozwiązanie

Jak można się tego spodziewać istnieje rozwiązanie, które upraszcza większość z problemów, które mogą się pojawić w kontekście interakcji między klientem a serwerem w architekturze mikroserwisów. Możemy wprowadzić dodatkowy komponent pośredni między warstwą aplikcji, a aplikacją kliencką, a jest nim API Gateway.

API Gateway to pewien rodzaj reverse proxy. Jego rolą jest odizolowanie reszty mikroserwisów od kwesti związanych z obsługą zapytań z aplikacji klienckich, a więc będzie on przekierowywał zapytania z klienta do odpowiednich serwisów. Odnosząc się do analogii z tytułu posta, API Gateway to drzwi wejściowe do naszego systemu. Z punku widzenia aplikacji klienckiej wszystko za tymi drzwiami jest ukryte i jeżeli nie podamy jej czegoś przez te drzwi to tego nie dostanie. Nie pozwalamy na wejście oknami czy też przez balkon.

Zalety

Co dzięki temu zyskujemy?

  1. Klient nie troszczy się ani o lokalizację mikroserwisów, ani o to w którym mikroserwisie zlokalizowany jest interesujący go zasób, ani o to ile instancji danego mikroserwisu jest dostęne, ani o to czy zmienimy strukturę mikroserwisów, ba, on nie troszczy się o to czy ma doczynienia z mikroserwisami w ogóle!
  2. Umożliwiamy odpytywanie systemu przez wygodne API, które może być dostosowanie API pod konkretnych klientów, bez konieczności implementacji tego w każdym mikroserwisie.
  3. Mamy tylko jeden punkt w którym uwierzytelniamy użytkownika.
  4. Możemy łączyć, filtrować, sortować i w różny sposób manipulować danymi w taki sposób by dostosować je do oczekiwań aplikacji klienckiej.
  5. Pozwalamy mikroserwisom rozmawiać między sobą w formacie, który jest dla nich wygodny, ponieważ nie ma to wpływu na klienta
  6. Możemy wersjonować API wystawione przez nasz Gateway w jeden sposób, a API wewnętrzne wykorzystywane przez mikroserwisy w naszym systemie w całkowicie inny sposób.
  7. Łatwiejsze zastosowanie load balancingu. W specyficznym przypadku API Gateway może być load balancerem.
  8. Łatwiej zastosować blue/green deployment. Dzięki Gateway’owi po deployu możemy przekierować ruch ze starych do nowych serwisów i staje się to bajecznie proste.

Wady

Jakie mamy minusy tego rozwiązania:

  1. Jako, że z natury mamy teraz pojedynczy punkt dostępu do systemu, w przypadku niedostępności tego serwisu, cały system staje się niedostępny. Jeżeli mamy problem z wydajnością w API Gatewayu wpływa on w znacznej mierze na cały system.
  2. Dodajemy następny komponent w systemie
  3. Minimalnie wydłużony czas względem bezpośredniego zapytania klient-mikroserwis

Miałem to szczęście, że dość szybko zostałem zaznajomiony ze wzorcem API Gateway dzięki czemu uniknąłem problemów, które przedstawiłem w początkowej części artykułu.Myślę, że zestawienie wad i zalet pokazuje tutaj jaki potencjał w nim drzemie zwłaszcza przy rozproszonych systemach.

Bibliografia i inne ciekawe linki:

Przenieś swój system do AWSa – krótki przegląd usług

AWS, czyli Amazon Web Services oferuje nam wiele usług, które możemy połączyć w zestaw realizujący zadania przed nim postawione. Wykorzystując już kilka z najpopularniejszych narzędzi, np. Lambda, RDS, VPC czy też S3 jesteśmy w stanie stworzyć zaawansowany system, nie wymagający armii ludzi odpowiedzialnych za infrastrukturę.

AWS Free Tier

Mało tego, dzięki programowi AWS Free Tier możemy znacząco obniżyć koszty funkcjonowania systemu w pierwszym roku korzystania z wielu usług, a warto zaznaczyć, że część z tych benefitów pozostaje po 12 miesiącach.

Cennik

Przy decyzji o wyborze oferty konkretnego dostawcy usług w chmurze warto przestudiować cennik pod kątem usług które zamierzamy wykorzystać. Pierwszym krokiem jednak jest zaznajomienie się z usługami, które mamy do wyboru, a trochę ich jest.

Popularne usługi

EC2 (Elastic Compute Cloud).

To nic innego niż serwer wirtualny, który można wykorzystać w dowolny sposób do uruchamiania naszych i nie tylko naszych aplikacji. Często może być wykorzystywany jako forma przejściowa dla usług uruchamianych na naszych serwerach, które chcemy przenieść do chmury. Podstawowymi plusami EC2 są: możliwość auto-skalowania, dostosowywania typu maszyny do software-u który będziemy na niej uruchamiali (optymalizacja pod kątem mocy obliczeniowej, pamięci RAM, GPU bądź też operacji dyskowych I/O). Płacimy za wykorzystany czas.

Lambda

Jest to niewielka (zazwyczaj) aplikacja mogąca wykonywać operacje w przypadku wystąpienia jakiegoś zdarzenia. Skąd się bierze to zdarzenie? Jest publikowane przez inną usługę i w zależności od tego przez jaką to inny jest też charakter tej wiadomości. Przykładowo, możemy mieć do czynienia z informacją o nowym obiekcie w usłudze S3 czy też zmianą elementu w tabeli. Potrzebujesz wywołać pewną operację w określonym czasie, z określonym interwałem? Także tutaj, nie ma problemu.

RDS (Relational Database Service)

Usługa za pośrednictwem, której mamy dostęp do relacyjnej bazy danych. Jakie silniki mamy do wyboru? Od MS SQL Server, Oracle i MySQL do MariaDB, PostreSQL i Amazon Aurora. A dlaczego używać RDSa zamiast własnego serwera z bazą danych? Amazon ułatwia nam zarządzania poprzez możliwość łatwiejszego skalowania, backupowania czy też patchowania.

VPC (Virtual Private Cloud)

Wszystko to co związane z sieciowością. Możemy tworzyć tu nasze sieci, podsieci, VPNy, grupy bezpieczeństwa, tablice routingu oraz wiele więcej 🙂 

ELB (Elastic Load Balancer)

Dzięki tej usłudze podzielimy zapytania do naszej aplikacji. Po co? W celu zapewnienia niezawodności oraz określonej wydajności naszego systemu. 

DynamoDB

Zarządzana baza danych typu NoSQL. Nie martwisz się o brak miejsca, cache, enkrypcję. Jeżeli struktura danych w twojej aplikacji na to pozwala to DynamoDB może być ciekawą alternatywą dla RDSa.

S3 (Simple Storage Service)

Można o tej usłudze myśleć jako o serwerze FTP. Umieszczamy tu wszelkiego rodzaju pliki, w przypadku aplikacji webowych możemy tu hostować np. obrazki czy mp3 do pobrania przez użytkowników. 

SNS (Simple Notification Service)

Niby „prosty” z nazwy serwis, ale pozwala na wiele sposobów rozgłaszania wiadomości. Dzięki niemu zrealizujemy powiadomienia SMS, e-mail czy też opublikujemy zdarzenie dostępne dla usługi Lambda.

SQS (Simple Queue Service)

Kolejka dla twoich aplikacji. Pozwala na komunikację między usługami poprzez wysyłkę wiadomości. Komponent produkujący wysyła wiadomości na kolejkę i wraca do przetwarzania. Komponent konsumujący przetwarza wiadomości i zdejmuje je z kolejki.

API Gateway

Swego rodzaju fasada stojąca pomiędzy klientami twojego API a twoim systemem. W najprostszym wypadku integrujemy API Gateway z Lambdą i mamy działające API bez potrzeby stawiania jakichkolwiek serwerów. API gateway może zapenić cache, wersjonowanie czy też łatwe zarządzanie definicją zasobów dostępnych poprzez API.

Cognito

Zarządzanie użytkownikami naszego systemu. Pozwala na autoryzację przy pomocy Facebooka i Googla. Ogromną zaletą jest prosta integracja z innymi serwisami np. API Gateway.

Cloud Formation

Serwis pozwalający na tworzenie zasobów w innych serwisach. Zasada jest prosta, w Cloud Formation mamy możliwość opisu i setupu innych serwisów. Wszystko w jednym miejscu.

Cloud Watch

Centrum monitoringu naszego systemu. Możemy tu sprawdzać status alertów, metryki czy też logi z innych serwisów AWS.

Cloud Trail

Akcje wywoływane przez użytkowników pozostawiają po sobie ślad. Nie wiesz kto usunął twoją bazę danych? Sprawdzisz to w Cloud Trail!

IAM (Identity and Access Management)

Pozwala na zarządzanie użytkownikami, kluczami (KMS – Key Management Service) i dostępem do określonych zasobów (przy użyciu polityk)

Iceberg, Antarctica, Cold, Arctic, Snow, Nature, Frozen

Czubek góry

To oczywiście tylko czubek góry, AWS posiada ogromną bazę serwisów i pracując na co dzień z AWS sam odkrywam często serwisy o których wcześniej nie słyszałem. W następnych wpisach postaram się przybliżyć więcej z tej bazy serwisów.

Mikroserwisy – smutne(?) fakty i hejting

Ten cały hype związany z mikroserwisami nie jest przypadkowy. Mikroserwisy , że wydają się być jedyną słuszną drogą, jeżeli nasz projekt ma nie powodować niekontrolowanego wybuchu śmiechu lub też wyrazów politowania na twarzy innych, którzy podążają za trendami i dawno mają już kilkanaście serwisów z których każdy oczywiście korzysta z osobnej bazy danych.

Dlaczego ten entuzjazm w temacie mikroserwisów należy brać z dystansem?

Ceną zalet które uzyskujemy (a opisałem je we wpisie: Mikroserwisy – wprowadzenie i dlaczego chcesz je mieć ) jest spora lista wad:

1. Podróż w nieznane.

Tytuł tego punktu jest celowo przekolorowany aczkolwiek jest w nim sporo prawdy. Musimy się liczyć z mniejszym zrozumieniem tematu pośród developerów. Mimo całego zamieszania wokół mikroserwisów w ostatnich latach, mimo wszystko architektura monolityczna jest dominującym sposobem tworzenia oprogramowania i często czynnikiem limitującym wprowadzenie takiej architektury może być brak odpowiednich kompetencji. Gdy sam zaczynałem swoją pracę nad projektem wykorzystującym mikroserwisy musiałem niemalże z dnia na dzień przestawić się na całkiem inne myślenie. Nie mając wcześniej styczności z tą architekturą chłonąłem wiedzę na jej temat niemalże z wypiekami na twarzy. Decydując się na tą architekturę trzeba być świadomym, że każdy z developerów będzie musiał wyruszyć w tą podróż i tu rodzi się pytanie czy każdy z nich będzie zdolny i wystarczająco zmotywowany by brnąć tą drogą.

2. Testowanie

Testowanie systemu jest utrudnione poprzez fakt, że trudniej nam odtworzyć stan systemu z chwili wystąpienia błędu. Patrząc pod innym kątem łatwiej testować problemy jeżeli są wyizolowane i dotyczą tylko i wyłącznie jednego mikroserwisu. Logowanie pozwala na złagodzenie problemów z testowaniem, aczkolwiek monolit tutaj wygrywa.

3. Kolaboracja między zespołami i inne implikacje wynikające z prawa Conway’a

Prawo Convey’a zgrubsza mówi o tym, że architektura systemu dąży do odzwierciedlenia struktury organizacyjnej ludzi ją tworzących.

Implementacja funkcjonalności wymaga kolaboracji pomiędzy różnymi serwisami może wymagać kooperacji między różnymi zespołami. Podział odpowiedzialności za mikroserwisy pomiędzy zespoły może wywoływać problemy gdy implementacja funkcjonalności przebiega na pograniczu wielu mikroserwisów. Nie jest może to do wielka wada, ale raczej wyzwanie i rzecz na którą warto zwrócić uwagę.

4. Dodatkowa złożoność związana z tworzeniem rozproszonego systemu

Z natury jeżeli mamy do czynienia z monolityczną architekturą, a komunikacja odbywa się wewnątrz procesu, unikamy konieczności martwienia się o to czy inny mikroserwis jest akurat dostępny, czy dane na których operujemy są wystarczająco aktualne (synchronizacja pomiędzy mikroserwisami) i wiele innych.

5.  Mikroserwisy od początku trwania projektu mogą być ryzykowne

Tworzenie architektury zorientowanej na mikroserwisy od zera może przynieść więcej strat niż pożytku. Mając ograniczoną więdzę nt. wymagań odnośnie tworzonego systemu (kto się z tym nie spotkał?) możemy dokonać błędnych decyzji nt. podziału funkcjonalności na mikroserwisy co niesie za sobą dużo większe konsekwencje niż w wypadku monolitu. Dlatego też często zalecaną praktyką jest tworzenie monolitu z luźno powiązanymi modułami, a następnie rozbijanie go na mikroserwisy gdy kształt systemu się wykrystalizuje. Unikamy wtedy przerzucania kodu pomiędzy różnymi mikroserwisami, a nawet pomiędzy różnymi zepołami!

6. Konieczna większa wszechstronność zespołów

Więcej umiejętności DevOpsowych wymaganych od zespołów rozwijających i utrzymujących mikroserwisy. Często wymaganiem jest aby zespół przeprowadził proces rozwijania mikroserwisu od implementacji do deploymentu i utrzymania. W monolitycznej architekturze mniej z tych obowiązków spoczywa na programistach. Wypuszczanie wersji zazwyczaj jest dużo rzadsze i często są obsługiwane przez dedykowanych ludzi.

7. Infrastruktura

Przy mniejszych systemach duży narzut tworzenia i utrzymywania infrastruktury, który niekoniecznie musi się opłacać.

8. Trudna kontrola niezawodności systemu.

W monolicie pula spraw które mogą pójść nie tak jest mniejsza niż przy mikroserwisach. Oczywiście jeżeli monolit leży to leży wszystko. W przypadku mikroserwisów często jesteśmy w dużym stopniu uzależnieni od infrastruktury sieciowej, dostęności zależnych mikroserwisów, szyny wiadomości i innych. To wszystko sprawia, że musimy być w stanie reagować na problemy w każdym z tych obszarów gdyż jeżeli mamy kilka komponentów z których każdy jest krytyczny dla działania systemu to prawdopodobieństwo, że system jest w pełni dostępny w danej chwili jest iloczynem prawdopodobieństwa dostępności każdego z tych komponentów.

Można złagodzić tutaj wymaganie dostępności poprzez komunikację asynchroniczną i architekturę zorientowaną na zdarzenia.

9. Krytyczność posiadania monitoringu i logowania

Jest to poniekąd implikacja kilku poprzednich punktów. Wiele miejsc w systemie wymaga uwagi więc kluczową sprawą jest posiadanie monitoringu i logowania. Nie zliczę ilości razy gdy załamywała mnie tymczasowa niedostępność logowania w systemie w którym musiałem zdebugować jakiś błąd. Nagle złożoność takiego problemu zwiększa się kilkakrotnie. Podobnie brak monitoringu sprawia, że błądzimy po omacku.

Podsumowanie

Każda w wymienionych cech systemów opartych o mikroserwisy powoduje, że warto dwa, a nawet trzy razy zastanowić się nad wprowadzeniem ich do naszego systemu. Mądzej czasami jest wstrzymać się z taką decyzją jak już będziemy ich pewni, nie dlatego, że jest to modne, ale dlatego, że przyniesie to wymierne korzyści w naszym konkretnym projekcie.

Chmura obliczeniowa – dlaczego? Zalety i wady

Cloud computing to często pojawiający się temat w dyskusjach o miejscu prowadzenia swojego biznesu w chmurze. Jednakże, przed podjęciem decyzji o wskoczeniu do AWS, Azure czy Google Cloud, warto zaznajomić się z konsekwencjami takiego wyboru.
Przygotowałem zestawienie, które może pomóc osobom borykającym się z dylematem co do wejścia na chmurę.

Zalety

  1. Niski próg wejścia. Jest to niezwykle istotne zwłaszcza w przypadku startupów nie przynoszących jeszcze zysków. Jesteśmy w stanie zaproponować i zwalidować nasze MVP (Minimum Viable Product) często nawet zerowym kosztem. Przykładowo AWS oferuje nam AWS Free Tier – https://aws.amazon.com/free/ a Azure https://azure.microsoft.com/pl-pl/free/
  2. Bezpieczeństwo dostępu do danych. O ile używamy usługi w chmurze w rozsądny sposób mamy do dyspozycji mechanizmy dzięki którym możemy w nocy spać spokojnie. Oczywiście należy być świadomym, że dane nie leżą u nas „na serwerze pod biurkiem” tylko są w bliżej nieokreślonym miejscu w chmurze i to po naszej stronie stoi odpowiedzialność za kontrolę dostępu do danych czy też ochrona haseł.
  3. Mniej kodu związanego z infrastrukturą. Używamy infrastruktury udostępnionej dla nas i możemy skupiać się na tym co jest istotne dla naszego systemu. Dzięki chmurze rozpowszechnił się popularny trend serverless.
  4. Brak potrzeby własnych serwerów. Poza finansowymi aspektami związanymi z zakupem, nie musimy się przejmować awariami tego sprzętu czy też serwisowaniem.
  5. Łatwa skalowalność. W zależności od konkretnej usługi często może dziać się automatycznie w zależności od aktualnego obciążenia systemu. Co to znaczy dla naszego biznesu? Jeżeli obłożenie jest nierównomierne w czasie (a zazwyczaj tak jest) to możemy cieszyć się niższymi rachunkami w czasie mniejszego obciążenia i jednocześnie być w stanie obsługiwać nawet kilkunastokrotnie zwiększone zapotrzebowanie na zasoby.
  6. Dostępność. Dzięki zarządzanym serwisom ciężar utrzymywania wysokiej dostępności jest w wielu aspektach zapewniany poprzez dostarczyciela usług w chmurze. SLA jest zazwyczaj na wysokim poziomie, zadowalającym dla 99% systemów. W przypadku systemów gdzie dostępność jest na prawdę rzeczą krytyczną można stosować podejścia zmniejszające ryzyko takie jak wykorzystanie więcej niż jednego dostawcy usług chmurowych.
  7. Koszty proporcjonalne do wykorzystania zasobów. W zależności od serwisu możemy dostosowywać koszt systemu poprzez zmianę parametrów wykorzystywanych usług takich jak przydział CPU, RAM, wielkość dysku. W przypadku innych serwisów możemy mieć możliwość płatności tylko za wykonaną pracę, czyli liczbę (mili)sekund w których nasz kod był wykonywany.
  8. Łatwe backupy. Tworzenie kopii zapasowych w przypadku baz danych, plików jest znacząco ułatwione, a serwisy często udostępniają możliwość eksportu danych do plików przechowywanych w innych usługach.
  9. Wielorakość serwisów pozwalających na wykorzystanie funkcjonalności: 
    1. Uruchamiania kodu w formie bezstanowych serwisów (np. Azure Functions, AWS Lambda) bądź też wirtualnych serwerów (np. Azure Virtual machines, AWS Elastic Compute Cloud – EC2)
    2. Baz danych (np. AWS RDS, DynamoDB, Azure Cosmos DB)
    3. DNS (np. AWS Route53, Azure DNS)
    4. CDN (np. AWS CloudFront, Azure Content Delivery Network)
    5. Serwer plików
    6. Fulltext search
    7. Kolejki wiadomości
    8. Wysyłka wiadomości
    9. Code integration/deployment
    10. Konteneryzacja (Docker)
    11. Big data i hurtownie danych, zarówno w procesie zbierania, przesyłania, przetwarzania jak i przechowywania danych
    12. Analiza danych
    13. Machine learning
    14. Zarządzanie, konfiguracja i monitoring naszych usług
    15. Internet of Things
    16. Usługi multimedialne 

Wady:

  1. Bezpieczeństwo danych. Tak tak, podobny punkt był też w zaletach 🙂 Brak kontroli z naszej strony co do tego w jaki sposób nasze są przetwarzane. W pewnych aspektach opieramy się na zaufaniu co do dostawcy usług chmurowych.
  2. Koszty
    1. Potrzebna jest ciągła analiza i kontrola kosztów tak by szybko identyfikować miejsca w których pieniądze zbyt szybko są spalane. Na szczęście mamy do dyspozycji narzędzia dzięki, którym nie wymaga to nie wiadomo jakiego nakładu pracy.
    2. Architektura systemu musi być rozwijana w oparciu o analizę przyszłego rozwoju projektu tak by dobrać odpowiednie rozwiązanie które spełnia wymagania i nie jest zbyt kosztowne.
  3. Vendor lock-in. Im więcej używamy usług danego dostawcy tym łatwiej dobrać kolejną usługę tego samego dostawcy (dzięki łatwej integracji między nimi), a tym samym tym bardziej jesteśmy uzależnieni od dokładnie tej chmury.
  4. Brak kontroli i uzależnienie od dostawcy. Nie mamy kontroli co do decyzji podejmowanych przez dostawcę usług chmurowych, który w jednej chwili może zdecydować o:
    1. likwidacji jednej z usług na której my polegamy
    2. wycofaniu się z interesu
    3. znaczącym podwyższeniu cennika usług
  5. Bezradność po wystąpieniu awarii. Jeżeli odpowiednio nie przygotujemy się na problemy z dostępnością danego serwisu to w przypadku wystąpienia danej trudności nie możemy już zbyt wiele zrobić niż czekać i przepraszać naszych klientów.
  6. Ochrona danych osobowych. Wiele z przepisów obowiązujących w danym kraju może obostrzać naszą swobodę w zakresie co do tego gdzie i w jaki sposób te dane mają być przechowywane.

Ogólny bilans, moim zdaniem, wychodzi zdecydowanie na plus. W generalnym rozrachunku przejście na zarządzane usługi z których składamy nasz system jest po prostu tańsze, jeżeli podejdziemy do tego tematu umiejętnie. Go cloud!

Mikroserwisy – wprowadzenie i dlaczego chcesz je mieć

Architektura mikroserwisów

Podział systemu na mikroserwisy jest to styl projektowania w którym dzielimy funkcjonalność na niezależnie deployowalne serwisy. Każdy z tych serwisów odpowiada za część funkcjonalności systemu, są one często usytuowane na różnych maszynach a komunikacja między odbywa się najczęściej przez HTTP/REST API lub też przez wiadomości przesyłane pomiędzy nimi. Nasuwa się pytanie po co? Po to by ułatwić sobie życie, wyeliminować nieprzespane noce związane z wielkimi i ryzykownymi wdrożeniami oraz by móc powiedzieć, że stosujesz mikroserwisy. Z doświadczenia wiem, że każdy z tych argumentów jest niesamowicie ważny i sprawia, że nie będziesz chcieć wracać do „starego” podejścia.

Wśród najczęściej wymienianych firm wykorzystujących z sukcesami mikroserwisy wymienia się takich potentatów jak: Uber, Netflix czy też PayPal.

Netfix

Uber

PayPal

Architektura oparta o mikroserwisy powinna charakteryzować się tym, że każdy z jej elementów jest luźno powiązany (loosely coupled) z innymi. Tak tak, powinna, lecz „sprawny” programista może ukryć zależności przed niewprawionym okiem i dalej tkwić w monolicie. Tutaj też potrzebny jest stały wysiłek by utrzymywać luźne powiązania, to nie silver bullet (niespodzianka!). Dzięki temu zmiany mogą być wprowadzane niezależnie, przez różne zespoły w różnych częściach systemu.

Wymóg tego by każdy mikroserwis mógł być niezależnie deployowalny jak i to, że ma być luźno powiązany z innymi powoduje, że chcemy też unikać ukrytych zależności takich jak współdzielenie baz danych pomiędzy mikroserwisami. Każdy mikroserwis powinien mieć swoją bazę danych. Taki wymóg oczywiście niesie za sobą konsekwencje i musimy zapewnić spójność danych pomiędzy wieloma serwisami.

2017-07-24 20_42_50-BlogGD - microservices pt1.png - Paint

Co zyskujemy?

Jakie są zalety takiej architektury? Na początku nie byłem świadomy ich istnienia, zaraz po ich poznaniu lista zalet to były po prostu obietnice. Teraz, po latach spędzonych na pracy nad mikroserwisami widzę, że nie były to puste obietnice.

1. Każdy serwis może być osobno rozwijany.

Wybór technologii dla jednego serwisu często (ale nie zawsze) nie narzuca technologii dla współpracujących serwisów. Mikroserwisy komunikujące się przez HTTP/REST są tu szczególnie łatwe w izolacji. Przykładowo w projekcie nad którym obecnie pracuję wykorzystujemy mikroserwisy w językach c#, python czy też javascript. Umożliwiamy dzięki temu eksplorację innych technologii poprzez wykorzystanie jej np. w jednym z mikroserwisów. Dzięki tego typu architekturze takie eksperymenty, nawet w wypadku nie do końca pozytywnych rezultatów, nie rzutują negatywnie na cały system.

2. Drastyczne skrócenie interwału pomiędzy releasami.

Dzięki możliwości osobnego wdrażania pojedynczych mikroserwisów, taki release jest zarówno mniej ryzykowny jak i częstszy. Jeden deploy? Dzień jak codzień. 3 deploye? Czemu nie? 5+ deploymentów? Bywa i tak 🙂

3. Zmniejszenie złożoności.

System, poprzez zmniejszenie powiązań między poszczególnymi jego częściami charakteryzuje się mniejszą złożonością co wpływa m. in. na błędogenność i czas jego życia. Architektura monolitu ma tendencje do niekorzystnego spadku produktywności rozwoju na dalszych etapach trwania projektu. Mikroserwisy „zrobione dobrze” są bardziej odporne na próbę czasu przede wszystkim z racji lepszej enkapsulacji logiki, możliwości łatwiejszej izolacji problemów, a także wymuszenia lepszej modularności systemu.

4. Skalowalność.

Umożliwienie skalowania poprzez zwiększanie liczby instancji danego mikroserwisu. Jeżeli zidentyfikujemy mikroserwis, który jest wąskim gardłem w naszym systemie możemy zwielokrotnić liczbę jego instancji poprawiając tym samym wydajność całego systemu. Nie jest to coś co otrzymujemy „za darmo”. Wymaga to odpowiedniej kultury devopsowej. Ba, w moim obecnym projekcie po dłuższym czasie nadal nie wygląda to tak jak powinno. Na szczęście coraz popularniejsze wykorzystanie usług chmurowych upraszcza wprowadzenie skalowalności znacząco! Przykładowo AWS EC2  czy też AWS ECS .

5. Bardziej naturalny podział pracy.

Lepsza alokacja zasobów, łatwiejszy podział prac i zwiększona odpowiedzialność zespołów za serwisy, którymi się opiekują to następne z zalet tego podejścia do projektowania systemu. Architektura monolityczna w której odpowiedzialność jest bardziej rozmyta nie sprzyja efektywnej pracy.

6. Circut breaker.

Jeżeli coś nie działa to jest duża szansa, że reszta systemu jest w stanie działać mimo to. Jak uzyskać tego typu niezawodność? Możemy wykorzystać tu podejście w którym definiujemy pewnego rodzaju komponent, który przy odpytywaniu zależności, którą jest inny mikroserwis, a właśniwie jego API, kontroluje stan zdrowia tego API. Jeżeli stan zdrowia przez kilka kolejnych zapytań nie jest zadowalający, przykładowo brak jest połączenia z serwisem, bądź zwraca on HTTP 500 możemy zdecydować o wyłączeniu funkcjonalności jaką oferuje. Dzięki temu nie odpytujemy na darmo serwisu który być może tylko tymczasowo jest niedysponowany oraz dajemy użytkownikowi szansę skorzystania z innych funkcjonalności systemu.

Oczywiście lista zalet nie wyczerpuje w pełni tematu, gdyż architekturę mikroserwisów można zrealizować na różne sposoby przez co możemy uzyskać nieco inny ich zestaw. Osobiście wydaje mi się, że zmniejszona złożoność systemu to największy plus gdyż jest to istotny czynnik który wpływa na opłacalność projektów, a nadzwyczaj często jest niedoceniany.

Bibliografia i inne ciekawe materiały: