Backend

Mikroserwisowa architektura na przykładzie Spring Cloud Netflix

programiści pracujący w biurze

W podejściu mikroserwisowym mamy wiele aspektów, o które trzeba się zatroszczyć. Mając na uwadze, że część z nich jest również używana w podejściu monolitycznym, niezbędnymi okazują się: Service Discovery, API Gateway (Routing), Server Side Load Balancing, Client Side Load Balancing, Circuit Breaker czy External Configuration. Dziś postaram się przedstawić, jak wygląda mikroserwisowa architektura na przykładzie Spring Cloud Netflix.

Service Discovery

W najprostszych słowach jest to serwis, który umożliwia rejestrowanie się nowych serwisów, jak i udostępnianie informacji o zarejestrowanych użytkownikach. Często są to implementacje wzorca klucz-wartosc, od którego wymagana jest duża niezawodność i szybkość. Bazowy serwis, który umożliwia zrównoważenie obciążenia poprzez wszystkie dostępne maszyny oraz, co za tym idzie, automatyczne skalowanie naszych aplikacji.

Najpopularniejsze implementacje Service Discovery to:

Service Discovery na przykładzie Eureka Server

Najprostsze sposoby na uruchomienie i zaczęcie pracy z Eureka:

Przejdźmy krok po kroku po źródłach niezbędnych do samodzielnego utworzenia i uruchomienia projektu Eureka Server. Kod źródłowy klasy głównej (oraz najważniejsza adnotacja w tym przykładzie @EnableEurekaServer):

Właściwości do zdefiniowania w application.properties:

W tej sytuacji powinniśmy mieć dostępny serwis Eureka pod adresem http://host:8761. Główna strona wygląda następująco.

spring cloud

Zawiera podstawowe informacje takie jak: aktualny czas, repliki (zarejestrowane, dostępne, niedostępne), czyli cały tak zwany status serwera oraz podstawowe informacje, czyli zużycie pamięci, dostępną pamięć, nazwę środowiska, na którym jest uruchomiona, ilość dostępnych procesorów, jak i czas pracy od uruchomienia.

Oczywiście, co najważniejsze z naszej perspektywy, to lista dostępnych serwisów.

Client Service Discovery na przykładzie Spring Boot Web

Naturalnie przejdziemy do prostych serwisów, które zarejestrują się w naszym Service Discovery. Przykładowy kod serwisu, gdzie najważniejsza z naszej perspektywy jest adnotacja @EnableDiscoveryClient:

Oraz application.properties

API Gateway

API Gateway jest punktem wejściowym naszej aplikacji, który przekierowuje żądania do odpowiednich serwisów w naszym środowisku. Podsumowując eksponuje publiczne API. Najpopularniejsze implementacje są udostępniane przez dostawców chmury. Oczywiście nic nie stoi na przeszkodzie, aby użyć innej implementacji, np.:

  • Nginx,
  • Zuul Netflix,
  • Amazon API Gateway,
  • Azure API Management.

API Gateway – na przykładzie Zuul Netflix

Zuul jest serwisem działającym na wirtualnej maszynie Javy, działający jako router, jak i również Server Side Load Balancing. Dzięki bazowaniu na filtrach: pre, route, post, error, umożliwia wiele funkcjonalności, takich jak:

  • security,
  • routing,
  • monitoring,
  • wstrzykiwanie danych (np. do nagłówków).

Client Side Load Balancing – Ribbon

Ribbona można używać bez dynamicznej informacji o dostępnych serwerach. Wtedy jesteśmy w stanie zdefiniować niezbędne właściwości w pliku application.properties z informacją pomiędzy jakimi serwerami klient ma balansować obciążenie. Przykład konfiguracji:

W naszym przykładzie chcemy, aby Ribbon pracował odpowiednio w architekturze mikroserwisów, która zakłada dynamiczną ilość instancji danego serwisu. Klient powinien mieć możliwość zdobywania tej informacji w czasie pracy.

Przykład application.properties Ribbon’a rejestrującego się w ‘Eureka Serwer’ i odświeżającego listę instancji interesującego go serwisu:

Konfiguracja użyta w projekcie:

Klasa startująca wraz z klientem:

API Gateway – Routing

Punkt wejściowy do naszej architektury. Przekierowuje żądania do odpowiednich serwisów. W naszym przypadku będzie to projekt open-source Zuul. Dzięki mechanizmowi filtrów jest w stanie filtrować ruch wejściowy, pozwalać na łatwy monitoring oraz zapewniać bezpieczeństwo i autentykacje. Musi zapewniać wysoką wydajność oraz skalowalność.

Przykładowo, korzystając ze środowisk chmurowych mamy odpowiedniki. I tak dla AWS jest dedykowany API Gateway zapewniający podobne funkcjonalności. Dla zobrazowania działania głównie routingu zbudujemy dwa różne proste serwisy oraz API Gateway na przykładzie Zuul.

Kod źródłowy serwisu pierwszego oraz application.properties:

Kod źródłowy serwisu drugiego oraz application.properties:

Najważniejszy nasz komponent, czyli Zuul service i jego application.properties:

Od tej chwili nasze żądania będą przekierowywane do prawidłowego serwisu poprzez określoną część adresu URL.

Server Side Load Balancing

W celu zobrazowania posłużymy się poznanym wyżej stackiem technologicznym: Eureka, Zuul i Spring Boot Web.

Chcemy uzyskać poniższą architekturę (poniższy screen), w której serwisy wykonujące operacje rejestrują się w Service Discovery (Eureka). O dostępne instancje dopytuje i odświeża informacje API Gateway (Zuul). Dla działającej całości potrzeba stworzyć klienta, który będzie odpytywał poprzez API Gateway nasze serwisy. Jedyną różnicą do poprzedniego podejścia jest dodanie Service Discovery w naszym przypadku Eureka Service, która udostępnia informacje o zarejestrowanych serwisach.

Stworzona architektura umożliwi łatwe skalowanie, w tym przypadku jeszcze ręczne. Jednak integrując z orkiestratorem np. Kubernetesem, Docker Swarm lub chmurą w łatwy sposób umożliwić autoskalowanie w zależności od obciążenia systemu.

spring cloud

Podsumowanie

Na pewno istnieją lepsze i nowsze rozwiązania do zabawy z mikroserwisami. Najlepiej pracować używając rozwiązania chmurowego, np. Amazon Web Services lub Microsoft Azure. Jednak w przedstawionym stacku technologicznym wszystko jest darmowe, nie musimy obawiać się o nieprzewidziane koszty, ponieważ podłączyliśmy dane karty kredytowej.

Próg wejścia wydaje się dosyć mały dla programisty Javy. A sama zabawa nie wymaga mocnego sprzętu. W zasadzie zostało już tylko życzyć dobrej zabawy.


Zainteresował Cię Netflix i chcesz dowiedzieć się więcej? Przeczytaj o architekturze chaosu, którą stosuje Netflix.

Zdjęcie główne artykułu pochodzi z unsplash.com.

Posiada ponad dziesięcioletnie doświadczenie w pisaniu aplikacji, głównie w języku Java. Zafascynowany kulturą DevOps i architekturą mikroserwisową, a co za tym idzie rozwiązaniami konteneryzacji Docker, Kubernetes i rozwiązań chmurowych. Szkoli, dzieli się wiedzą i mentoruje w szkołach IT. Miłośnik dobrych meetup’ów.

Podobne artykuły