Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach?

Dawid Wieczorek | Rozwój oprogramowania | 10.11.2021

Mikroserwisy

Mikroserwisy są odpowiedzią na problemy związane z tworzeniem i utrzymaniem monolitycznych systemów. W czasie, gdy aplikacje muszą być stale rozwijane, a jednocześnie dostępne dla użytkowników, mikrousługi stają się state-of-the-art w rozwoju oprogramowania. W jakich projektach się sprawdzą, a w których rozsądniej jest pozostać przy konstrukcji monolitu?

 

Mikroserwisy – ich popularność rośnie

Pojęcie architektury mikroserwisowej pojawiło się po raz pierwszy na scenie IT w okolicach roku 2013. Od tego czasu jej popularność wydaje się poruszać tylko w jednym kierunku – w górę! Potwierdzenie takiej hipotezy możemy znaleźć na przykład w raporcie „Microservices adoption” przygotowanym przez firmę O’Reilly w roku 2020, z którego wynika, że 77% firm, w których pracują respondenci, stosują taką architekturę. Jednocześnie aż 92% pytanych określiło zastosowanie mikroserwisów jako sukces  z perspektywy oczekiwanych zysków, które przynosi takie podejście.

architektura mikroserwisów

W innej ankiecie przeprowadzonej przez IBM Market Development & Insights o opinię zapytanych zostało ponad 1200 osób z branży IT, w tym dyrektorzy techniczni, menedżerowie i programiści pracujący w firmach, które stosują lub planują zastosować architekturę mikroserwisową.

Wyniki są jednoznaczne:

  • 87% użytkowników zgadza się, że wysiłek oraz koszty poniesione na wdrożenie architektury mikroserwisowej opłacały się.
  • 84% użytkowników zgadza się, że stosowanie mikroserwisów ułatwia pracę obecnym pracownikom oraz pozwala na przyciągnięcie nowych.
  • 77% użytkowników zgadza się, że mikroserwisy są sprawdzonym i niezawodnym modelem tworzenia aplikacji.
architektura mikroserwisów

Chociaż jest to oczywiście bardzo wątpliwa miara, z własnej perspektywy programisty – sądząc po opisach projektów w ofertach pracy – mógłbym stwierdzić, że praktycznie większość projektów jest aktualnie tworzona w architekturze mikroserwisowej. Pomimo że na takie opisy musimy spojrzeć z przymrużeniem oka, widać, że mikroserwisy szybko stają się standardem w świecie IT.

Jak architektura mikroserwisów odpowiada dziś na potrzeby rozwoju systemów?

Jednym z największych wyzwań architektury mikroserwisowej jest silna zależność od infrastruktury (serwerowej, sieciowej itp.), a co za tym idzie – zwiększona potrzeba inwestycji w jej tworzenie. Jeszcze kilka lat temu było to jednak dużo większym wyzwaniem niż dzisiaj. W odpowiedzi na potrzeby nowego modelu powstał szeroki wachlarz narzędzi, które usprawniają pracę w rozproszonym środowisku.

  • Kontenery – na potrzeby orkiestracji serwisami powstały rozwiązania do zarządzania, automatyzacji i skalowania aplikacji kontenerowych. Dzisiaj możemy wybierać spośród wielu narzędzi, od prostych i niewymagających, jak Docker Swarm, po zakrojone na największą skalę rozwiązania enterprise, jak chyba najpopularniejszy Kubernetes lub Openshift. Dodatkowo dostępne są rozwiązania chmurowe, jak AWS Fargate czy Google Cloud Run. Każda z platform chmurowych oferuje również zarządzane przez siebie serwisy Kubernetes, jak AWS EKS lub Google GKE. Wszystkie wymienione narzędzia w znacznym stopniu zmniejszają dzisiaj próg wejścia do projektów opartych na mikroserwisach pod względem infrastruktury serwerowej. Należy jednak liczyć się z kosztami ich utrzymywania.
  • Service Mesh – w odpowiedzi na wyzwania związane z silną zależnością od infrastruktury sieciowej powstało wiele rozwiązań, z których najpopularniejszy jest obecnie model Service Mesh. Tutaj znowu mamy wybór pomiędzy lekkimi rozwiązaniami jak Linkerd, Kuma czy Maesh a bardziej wymagającymi, jak Istio, oraz rozwiązaniami chmurowymi, jak AWS App Mesh. Jak widać, stworzenie infrastruktury sieciowej dla swojej aplikacji mikroserwisowej nie stanowi dzisiaj tak dużego wyzwania jak kiedyś, chociaż sama zależność od sieci jest i zawsze pozostanie wyzwaniem.
  • Narzędzia do monitorowania – cytując głównego inżyniera firmy Lyft, Matta Kleina, który brał udział w przejściu firmy z monolitu na mikroserwisy:

Inną istotną zmianą, która pojawia się wraz z rozwojem mikroserwisów, jest obecność sieci jako niestabilnego elementu, którego nie da się uniknąć. Każdy programista musi w końcu poradzić sobie z problemami sieciowymi, zarówno jeśli chodzi o transport, jak i o znacznie bardziej złożone narzędzia wymagane do debugowania.

Wspomniane wyżej narzędzia wspierające pracę i debugowanie aplikacji kontenerowej również przeżyły rozkwit i dzisiaj możemy wspierać się narzędziami do monitorowania, logowania i tracingu. Rozwiązania takie jak Prometheus, ELK czy AWS CloudWatch pozwalają sprostać wyzwaniom utrzymywania lub debugowania aplikacji w rozproszonym środowisku.

Bolączki monolitycznej aplikacji

Powstanie i ostateczny sukces mikroserwisów nie wziął się oczywiście z niczego. Jest to raczej odpowiedź na trudności związane z klasycznym podejściem, które w wielu przypadkach przeważają nad plusami podejścia monolitycznego.

Z perspektywy biznesu i użytkowników

Z perspektywy biznesowej możemy wymienić wiele wad, które mogą wpłynąć na doświadczenia użytkowników i tym samym – na ostateczny sukces aplikacji:

  • Wprowadzanie nawet najmniejszej zmiany wymaga reinstalacji całej aplikacji, co prowadzi do tymczasowej niedostępności aplikacji, która w nowoczesnym świecie jest praktycznie niedopuszczalna dla komercyjnych rozwiązań.
  • Poszczególne komponenty systemu są ze sobą ściśle powiązane, co oznacza, że nawet mała zmiana w kodzie może negatywnie wpłynąć na całą aplikację, a tym samym być odczuwalna dla 100% jej użytkowników.
  • Trudności nastręcza skalowanie aplikacji w odpowiedzi na zmienny ruch. Niemożliwe jest też oczywiście skalowanie poszczególnych komponentów systemu, a tylko całej aplikacji. W momencie przeciążenia aplikacja może stać się niedostępna dla części użytkowników.
  • Brak skalowalności może się przekładać na wyższe koszty utrzymania aplikacji.
  • Spowolnienie prędkości rozwoju i udostępniania nowej funkcjonalności.
  • Zdecydowanie zmniejszona możliwość zastosowania nowych technologii, których wprowadzenie byłoby zbyt kosztowne i wymagałoby poświęcenia więcej czasu przez programistów (czy nawet zatrudnienia nowych).

Z perspektywy developera

Patrząc z perspektywy developera pracującego nad monolitem, możemy dodatkowo wymienić jeszcze kilka wad:

  • Spora baza kodu jest trudna w zrozumieniu, co od nowego programisty wymaga dużo czasu na poznanie i wdrożenie. Spowalnia ona również codzienny cykl wprowadzania zmian i ich testowania (pamiętajmy, że każda, nawet drobna zmiana, może mieć wpływ na całą aplikację).
  • Rozmyta odpowiedzialność oraz brak poczucia własności kodu może wpływać demotywująco na programistę. W przeciwieństwie do całkowitej własności części systemu, którego czujemy się autorem w przypadku tworzenia i utrzymywania konkretnych mikrousług.
  • Trudność we wdrożeniu nowych, interesujących technologii, ponieważ każda taka inicjatywa oznacza wprowadzenie zmian w całej bazie kodu aplikacji.
  • Mniejsze możliwości rozwoju osobistego – w dynamicznie zmieniającym się świecie IT rozważne jest, aby developer ciągle się rozwijał i zawsze dysponował aktualną wiedzą. Praca nad aplikacją monolityczną może nie być najlepszym krokiem, gdyż nie ma się styczności z szeroką wiedzą wymaganą w świecie mikroserwisów.

Zalety wykorzystania architektury mikroserwisów

Przejdźmy teraz do możliwości i udogodnień dostępnych przy wykorzystaniu mikroserwisów.

Z perspektywy biznesu i użytkowników

  • Łatwa redundancja elementów (czyli duplikowanie poszczególnych komponentów celem zapewnienia ciągłości pracy w razie awarii) i ich skalowanie, zgodnie z aktualnym zapotrzebowaniem, a tym samym większa dostępność systemu. Maleje tym samym ryzyko, że użytkownik nie będzie mógł skorzystać z naszej aplikacji.
  • Luźne powiązanie poszczególnych serwisów pozwala na niezależny rozwój funkcjonalności i szybsze ich wdrożenie.
  • Wdrożenia mogą następować niezależnie od siebie i praktycznie nie wpływają na dostępność całości systemu dla użytkowników.
  • Mikroserwisy są idealnie dostosowane do wykorzystania architektury typu serverless, która w odpowiednich zastosowaniach pozwoli zaoszczędzić na kosztach infrastruktury.
  • Łatwiejsze testowanie małych komponentów pozwala na uniknięcie wystąpienia uciążliwych dla użytkowników bugów.
  • Wdrożenie nowych technologii, z korzyścią dla użytkownika, jest zdecydowanie łatwiejsze i może odbywać się na poziomie poszczególnych serwisów.

Z perspektywy developerów

Z zastosowaniem mikroserwisów łączy się też kilka pozytywów dla pracujących z nimi developerów:

  • Pojedyncze usługi są łatwiejsze w zrozumieniu, ich baza kodu jest też odpowiednio mniejsza. Ułatwia to pracę nad nowymi funkcjonalnościami i ich testowaniem, ale również usprawnia wdrożenie nowej osoby w projekt.
  • Każdy z twórców danej usługi czuje się za nią odpowiedzialny i dobrze zna domenę biznesową powierzonej mu części.
  • Możliwość eksperymentowania i poszerzania wiedzy o nowych technologiach przy tworzeniu nowych funkcjonalności.
  • Mniejsza koncentracja wiedzy wśród programistów, co pozwala uniknąć sytuacji, w której brak kluczowej osoby może okazać się poważnym problemem.
  • Odpowiedzialność za poszczególne komponenty jest podzielona pomiędzy oddzielne zespoły, co pozwala na skuteczne dyżurowanie i szybką reakcję odpowiednich dla danego problemu osób.
Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach? - python cover 1
Chcesz dowiedzieć się więcej o Spring Reactive Web oraz RSocket w mikroserwisach?
Zobacz nagranie webinaru Marcina Chrosta i Łukasza Pyrkosz: Reaktywność nie zna kompromisów. Zobacz nagranie

Wady mikroserwisów

Z perspektywy biznesu

  • Początkowy koszt wykonania aplikacji w architekturze rozproszonej może być wyższy niż w przypadku monolitu. Podwyższony koszt to przede wszystkim wydatek na infrastrukturę oraz zaangażowanie odpowiednich specjalistów DevOps, odpowiedzialnych za jej utrzymanie.
  • Ryzyko, że realizacja aplikacji będzie utrudniona lub nawet się nie powiedzie, jest większe z powodu nieodłącznej złożoności takiej architektury.
  • Wdrożenie takiej architektury wymaga zmiany podejścia całego zespołu pracującego nad aplikacją. Decyzyjność przesuwa się od menedżerów i architektów w stronę poszczególnych zespołów. Z taką autonomią przychodzi większa potrzeba skutecznej komunikacji i współpracy pomiędzy zespołami.

Z perspektywy developera

  • Funkcjonalność wymagająca bezwzględnej spójności danych (transakcje bankowe itp.) jest trudniejsza do implementacji, ponieważ wymaga dodatkowej koordynacji całego procesu, który może być realizowany w kliku usługach. W aplikacji monolitycznej taki problem byłby rozwiązany za pomocą transakcji na poziomie bazy danych.
  • Debugowanie może być utrudnione z powodu rozproszenia logiki w wielu usługach, których logi mogą zawierać wskazówki o błędzie. Dodatkowymi źródłami błędów mogą okazać się punkty komunikacji pomiędzy poszczególnymi usługami.
  • Testowanie integracyjne nowych funkcjonalności staje się bardziej skomplikowane, ponieważ nie ma możliwości przetestowania całego systemu rozproszonego.

Mikrousługi a podejście DDD

Większość korzyści płynących z zastosowania architektury rozproszonej jest efektem stworzenia prawidłowego podziału odpowiedzialności poszczególnych usług i wyznaczenia sposobu komunikacji między nimi. Celem jest stworzenie silnej spójności serwisów i jednocześnie luźnego powiązania pomiędzy nimi. Innymi słowy, rzeczy, które zwykle wymagają wspólnej zmiany, powinny należeć do jednego serwisu. Bez odpowiedniego podziału zamiast korzyści, jak niezależna implementacja czy skalowalność usług, możemy skończyć z niewydajnym lub trudnym w utrzymaniu projektem. W praktyce jest to oczywiście trudniejsze do zrealizowania niż w teorii – wstępne założenia lub późniejsze wymagania ulegają zmianie. Z tego powodu możliwość łatwego wprowadzania zmian jest kolejnym krytycznym aspektem podczas projektowania każdej aplikacji.

Podejście Domain-driven design (DDD) jest kluczowym narzędziem podczas projektowania architektury mikroserwisowej, tak przy rozbijaniu aplikacji monolitycznej, jak i tworzeniu aplikacji od zera.

Czym jest DDD? Czyli jak okiełznać system podczas tworzenia oprogramowania

DDD zapoczątkowane w książce Erica Evansa to zestaw zasad i wzorców, których celem jest wsparcie tworzenia aplikacji rozproszonych w oparciu o model domeny biznesowej będącej tematem tworzonego oprogramowania. Zespół programistów wraz z ekspertami domeny biznesowej tworzą model biznesowy w wypracowanym wspólnym języku, tzw. ubiquitous language. Następnie stworzony model jest tłumaczony na poszczególne usługi, ustalane są protokoły komunikacji między nimi oraz tworzone są zespoły odpowiedzialne za poszczególne serwisy. W całym procesie  pomocny może być dodatkowo event storming. Wzorce DDD mają na celu ułatwienie zrozumienia domeny i zależności w niej zachodzących. Od tego już niedaleko do wyznaczenia granic w domenie, a tym samym wypracowania podziału na usługi zmapowane na domenę biznesową.

Mikroserwisy w praktyce – case study

W istniejącej od wielu lat platformie e-commerce pojawiło się nowe wymaganie biznesowe, polegające na masowym tworzeniu nowych ofert na bazie plików. Narzędzie miało być głównie stosowane przez sprzedawców oferujących szeroki asortyment, którzy w ten sposób mogliby usprawnić i zautomatyzować interakcję z platformą w kwestii tworzenia i edycji swoich ofert.

Wspomniana platforma, chociaż została stworzona jako monolit, od dawna jest już rozbita i rozwijana w architekturze mikroserwisowej. Zadanie zlecone jednemu z zespołów JCommerce polegało więc na stworzeniu nowej mikrousługi (ostatecznie powstało ich kilka) odpowiedzialnej za realizację tej funkcjonalności. Prace nad rozwiązaniem postępowały bez ingerencji w resztę usług aplikacji, której rozwój mógł postępować niezależnie. Jedynym punktem styku z resztą platformy stała się inna mikrousługa, a szczegóły komunikacji i implementacji zostały ustalone pomiędzy zespołami odpowiedzialnymi za obie usługi. Również decyzje o wyborze technologii (jak baza danych czy nawet język programowania) pozostawały w dużej mierze w gestii zespołu. Po wdrożeniu na produkcję zespół JCommerce jest w stanie dynamicznie skalować ilość instancji usługi adekwatnie do liczby zapytań od użytkowników.

Taka autonomia jest kluczowa przy rozwoju aplikacji, nad którą kolektywnie pracują nawet setki zespołów. Trudno sobie wręcz wyobrazić skuteczne wdrożenie takiej funkcjonalności, gdyby cala platforma była nadal monolitem.

Podsumowując: czy architektura mikroserwisowa sprawdzi się w moim projekcie?

Odpowiedź na to pytanie musi być niestety wymijająca – to zależy. Decydując się na dany model, akceptujemy kompromis, czyli przyjmujemy go razem z jego mocnymi i słabymi stronami.

Gdy chcemy rozbić monolit

Jeżeli rozważamy rozbicie istniejącej aplikacji monolitycznej, decyzja jest może prostsza, zmotywowana wszystkimi bolączkami, które nastręcza monolit. W tym przypadku jednym ze sprawdzonych podejść jest odcinanie mniejszych serwisów z głównego bloku, aż w końcu nowe funkcjonalności będą mogły być tworzone w całkowitej izolacji, a mniejszy centralny monolit będzie stopniowo wygaszany.

architektura mikroserwisowa całej aplikacji

Gdy tworzymy aplikację od podstaw

Jeżeli jednak rozpoczynamy tworzenie aplikacji od zera, jednym z kluczowych względów, na którym możemy oprzeć decyzję, jest rozmiar docelowej aplikacji. W przypadku tworzenia MVP aplikacji, najważniejsza jest szybkość dostarczenia funkcjonalności kosztem innych priorytetów. Zgodnie z zasadą YAGNI (You Ain’t Gonna Need It) nie ma sensu inwestować w zastosowanie zbyt wyszukanych narzędzi, jeśli nie mamy pewności, że aplikacja będzie się cieszyć odpowiednim poziomem zainteresowania.

architektura mikroserwisów

Taka sytuacja przemawia więc za zastosowaniem monolitu, który dopiero w dalszej fazie zostanie podzielony – ciekawym rozwiązaniem może być zastosowanie architektury tzw. modularnego monolitu, w której funkcjonalności rozbite są na poszczególne moduły tworzone w ramach jednej aplikacji.

Jeśli jednak wiemy, że rozmiary docelowej aplikacji uzasadniają wstępną inwestycję, wtedy architektura mikroserwisowa jest jak najbardziej rozsądnym wyborem.

Autorem wpisu jest:

Senior JAVA Developer

Dawid jest Senior Software Developerem z 8-letnim doświadczeniem w tworzeniu oprogramowania, głównie w języku Java. Sporo korzysta również z Kotlina oraz posiada certyfikat architekta AWS. W pracy ceni sobie przede wszystkim możliwość rozwoju. Prywatnie stara się być na bieżąco z nowinkami i ciągle się dokształca. Dodatkowo pomaga też tym, którzy chcą wejść do świata IT, dzieląc się swoją wiedzą i doświadczeniem.

Dodaj komentarz: