Jak skalujemy architekturę? Mikroserwisy.

O jakiej skali mówimy?

Codziennie pobieramy informacje o cenach dla 250 milionów produktów. W tym celu wykonujemy ponad 150 milionów zapytań i pobieramy oraz procesujemy ponad 20 terabajtów danych. Warto zaznaczyć, że wartości te z dnia na dzień wzrastają. Jest to ilość danych wymagająca bezbłędnej i niezawodnej pracy systemu przez całą dobę. W jaki sposób jesteśmy w stanie to zrobić? Odpowiedzią jest skalowalna architektura systemu oparta o mikroserwisy.

 

Monolit, czy to już faux pas?

Architektura monolityczna to tradycyjny model projektowania systemu/aplikacji
istniejąca w branży od wielu lat. Polega na umieszczeniu wszystkich części systemu w jednej bazie kodu i wdrażaniu jej jako całości na jednym serwerze.
Główną zaletą takiego systemu jest łatwość projektowania oraz niski początkowy koszt infrastruktury. Często aplikacje zaczynają jako monolity bo jest to łatwiejsze, tańsze i szybsze rozwiązanie. Przy dużym tempie rozwoju i potrzeby skalowalności szybko okazuje się jednak, że jest to rozwiązanie niewystarczające. Koszt rozbudowy i modernizacji monolitu z czasem zwiększa się do ogromnych wartości, przy których łatwiej jest zaprojektować aplikację od nowa.

Najważniejsze zalety i wady architektury monolitycznej:

Zalety:

● niskie koszty projektowania oraz infrastruktury,
● mniejszy stopień skomplikowania systemu,
● wysoka wydajność dla jednego procesu,
● większe bezpieczeństwo komunikacji między modułami – odbywa się w pamięci i nie opuszcza serwera,
● łatwiejsze testowanie i debugowanie.

Wady:

● podatny na awarie, wszystkie moduły nie działają jednocześnie,
● trudne i kosztowne wprowadzanie zmian,
● trudność z jednoczesną pracą wielu osób,
● często jeden błąd oddziałuje na całą aplikację, w przypadku błędu, który pochłania dużą ilość zasobów (CPU, RAM) ciężko jest stwierdzić, która część systemu za to odpowiada,
● bardzo ograniczona skalowalność, zazwyczaj tylko multiplikacja całych aplikacji a nie pojedynczych modułów.
Tego typu podejście nadal jest stosowane w przypadku mniejszych systemów lub bardzo starych, nierozwijanych od dawna aplikacji. Coraz częściej jednak wypierane jest przez mikroserwisy.

 

Czym są Mikroserwisy?

Mikroserwisy to obecnie jeden z najważniejszych trendów technologicznych. Jest to pojęcie opisujące sposób projektowania architektury systemu polegający na stworzeniu wielu połączonych ze sobą mniejszych modułów realizujących pojedyncze zadania i komunikujących się ze sobą poprzez rozmaite protokoły komunikacyjne.

Główne zalety takiego podejścia:
● wysoka wydajność i szybkość działania,
● wysoka skalowalność,
● odporność na awarie – łatwość zastępowania pojedynczych części systemu innymi,
● lepsza kontrola narastającego długu technologicznego – łatwiej jest modernizować mniejsze części systemu w oderwaniu od siebie,
● mniejsza zależność od konkretnego dostawcy usługi, łatwo jest uruchomić potrzebną część systemu np. na serwerze od innego dostawcy.

Jak każdy system, rozproszone podejście to posiada również wady:
● architektura jest bardziej skomplikowana, rozłożona,
● często efekt końcowy danej operacji przechodzi przez wiele modułów co wpływa na trudność i pracochłonność debugowania,
● komunikacja między modułami odbywa się po sieci, z czego wynika większa praca potrzebna na zapewnienie bezpieczeństwa.

 

Przykład architektury

Jak można zrealizować rozproszony system do pobierania i przetwarzania danych? Oto uproszczony przykład obrazujący schemat pobierania jednego źródła danych w oparciu o mikroserwisy.

Podstawą komunikacji w tym przypadku jest system kolejek, na które są wysyłane i odbierane różnego rodzaju wiadomości zawierające zarówno parametry wejściowe dla modułów jak i rezultaty ich działania. Może to być dowolny system, dobrym przykładem będzie RabbitMQ. Jeden serwer kolejek może przeprocesować kilkadziesiąt tysięcy wiadomości na sekundę.

Dzięki temu możliwe jest wyodrębnienie pojedynczych modułów realizujących konkretne zadania:
● scheduler – moduł inicjujący flow, zlecający np. pobranie konkretnego źródła danych. Wysyła inicjującą informację na odpowiednią kolejkę.
● queues – system imiennych kolejek, np. RabbitMQ,
● coordinator – moduł koordynujący pracę workerów, analizuje i wybiera kolejne URL’edo pobrania przez workery, zbiera statystyki,
● workery – grupa prostych i jednakowych modułów, których zadaniem jest pobranie URL’a z kolejki, pobranie zawartości strony internetowej, przetworzenia danych oraz zwrócenia rezultatu na osobną kolejkę,
● guardiany – grupa modułów, których zadaniem jest odebranie wyników prac workerów oraz wydajne i poprawne zapisanie ich do odpowiedniej bazy danych.

Podejście takie jest łatwo skalowalne – jeżeli potrzebujemy pobierać i przetwarzać więcej wystarczy zwiększyć liczbę workerów oraz guardianów. Ze względu na jeden ogólny system komunikacji każdy moduł może być stworzony w innej technologii oraz uruchomiony na osobnym serwerze. Ponadto każda część systemu może być rozwijana przez inny zespół programistów. W przypadku awarii któregoś z serwerów łatwo jest uruchomić odpowiednie moduły na innym, gwarantując tym samym ciągłość pracy i niezawodność systemu.

 

Podsumowanie

Podsumowując, rozproszona architektura w oparciu o mikroserwisy to rozwiązanie bardziej skomplikowane niż monolit, wymagające większej ilości pracy i uwagi zarówno na etapie projektowania jak i wdrażania. Zapewnia jednak wysoką skalowalność oraz odporność na awarie. Z pewnością jest to dobre rozwiązanie dla firm, które szybko potrzebują wdrażać nowe zmiany, skalować swój biznes i pozwolić na autonomiczny i równoległy rozwój wielu jego gałęzi. Jeżeli jednak istnieje potrzeba szybkiego i tańszego uruchomienia mniej skomplikowanego projektu, to monolit nadal jest opcją do rozważenia.