Przychodzi taki moment w życiu aplikacji, kiedy zaczyna cieszyć się ona coraz większą popularnością. Wówczas zwiększa się liczba żądań od użytkowników, które należy obsłużyć, co powoduje zmianę rodzajów problemów do rozwiązania. Nie można myśleć już tylko o funkcjonalności oprogramowania, ale trzeba zacząć również rozważać kwestię skalowalności. Właśnie z tego powodu powstała koncepcja systemów rozproszonych. Jest to nic innego jak fizyczne rozdzielone aplikacje, które komunikują się ze sobą za pomocą sieci. Są one niezależne i każda z nich posiada swój własny kontekst działania, czyli np. moduł sprzedaży czy moduł logistyczny. W ten oto sposób dochodzimy do koncepcji architektury mikroserwisów.

Jak działają mikroserwisy?

System jako całość musi na początku zostać podzielony według funkcjonalności np. przy pomocy Domain-Driven Design, a nie tak jak ma to miejsce przy architekturze warstwowej - biorąc pod uwagę aspekty techniczne. Każda z części może powstać w oparciu o inną technologię oraz architekturę. Nie ma to najmniejszego znaczenia. Ważne jest, żeby miały wspólną nić porozumienia w postaci sieci (najczęściej REST albo kolejki) oraz, aby każda taka usługa mogła być wdrożona w odosobnieniu od innych aplikacji.

Na pewno rozgorzało wiele dyskusji na temat tego jaka powinna być wielkość danego mikroserwisu. Jedni upierają się, że musi to być co najwyżej kilkaset linijek kodu, inni natomiast, że niekoniecznie. Jednak nie rozmiar ma tutaj znaczenie. Najważniejsze jest, aby były to autonomiczne aplikacje, które razem tworzą większą całość. W ten sposób do każdej lub kilku usług może powstać dedykowany zespół deweloperski.

Schemat architektury mikroserwisowej
Schemat architektury mikroserwisowej

Tak jak każda róża tak i to rozwiązanie ma swoje kolce. Upraszczając poszczególne aplikacje problem złożoności przenosi się w inne miejsce. Staje się nim komunikacja pomiędzy usługami oraz infrastruktura. Należy uwzględnić obsługę sytuacji wyjątkowych, gdy np. zabraknie połączenia z siecią. Potrzebne będą również narzędzia monitorujące kondycję poszczególnych aplikacji, aby można było szybko zareagować w przypadku wystąpienia awarii. Uwagę należy także zwrócić na mechanizmy logujące wywołania poszczególnych usług, żeby mieć pojęcie jaki jest dokładny przebieg działania systemu. Takich problemów jest na pewno o wiele więcej i trzeba mieć przygotowany scenariusz na każdą ewentualność.

Za i przeciw

Bezapelacyjną zaletą architektury mikroserwisowej jest możliwość nieograniczonego skalowania aplikacji. Jeżeli dana usługa wymaga, żeby obsługiwać większą liczbę żądań to można bez problemu tylko jej zwiększyć zasoby. Nie istnieje potrzeba, aby rozszerzać całą aplikację. Same usługi stają się łatwiejsze w utrzymaniu z powodu działania tylko w jednym zakresie funkcjonalnym. Nie ma takiej złożoności jak w przypadku aplikacji monolitycznej.

Oczywiście trudniejsze staje się zarządzanie całym systemem. Trzeba zwiększyć nakłady pracy, aby dobrze zaprojektować oraz zaimplementować komunikację pomiędzy poszczególnymi mikroserwisami. Należy również zainwestować w utrzymanie złożonej infrastruktury, czyli np. w logowanie czy autoskalowanie.

Podsumowanie

Wydaje mi się, że naprawdę ciężko jest zaprojektować taką architekturę od początku posiadając małą wiedzę o domenie. Mikroserwisy powinny powstać w drodze ewolucji oprogramowania. Na początku preferowane jest rozpoczęcie pracy z monolitem i wyodrębnianie w ramach jego rozwoju kolejnych usług. Tutaj oczywiście przydać się może technika Domain-Driven Design, które pomoże nam w znalezieniu kolejnych obszarów funkcjonalnych. Warto oczywiście mieć cały czas na uwadze wizję systemu, aby wiedzieć do czego chcemy dążyć.

Kolejny wpis architektoniczny za nami. W tej serii chciałbym jeszcze poruszyć dwie możliwe architektury: reaktywną oraz serverless. Z tego powodu nie ma na co czekać i widzimy się w następnym artykule!