Kurs Java

Service Registry Eureka

Mikroserwisy i podejście do nich powinno być wykonywane z zastosowaniem wzorców projektowych. W tym wpisie przybliżymy Wam wzorzec Service Discovery. Wzorzec ten wykorzystywany jest do rejestracji i udostępniania różnych instancji mikroserwisów w celu realizacji zadań, o które proszą klienci usługi.

Jak to się dzieje ? Czy robimy to sami? Nie, w tym celu stosuje się rejestr (registry), który dokładnie wie jakie mikroserwisy oraz ile ich instancji jest do naszej dyspozycji.

Najpierw mikroserwisy dodają się do rejestru, a następnie ten rejestr udostępnia je zainteresowanym klientom. Tak więc klienci nie odwołują się do tych mikroserwisów bezpośrednio, tylko korzystają z pośrednika w postaci rejestru. To ten pośrednik wybiera, która instancja mikroserwisu wykona daną pracę. Innymi słowy „odkrywa, który serwis wykona pracę” – czyli wykona "service discovery".
Java CheckedException

Nasze pierwsze Service Registry

W ramach zadania przygotujemy sobie następujące elementy:
  • Projekt eureka.server
    To właśnie będzie nasz rejestr mikroserwisów, a zarazem pośrednik w komunikacji z nimi.
  • Projekt eureka.microservice
    Implementacja mikroserwisu, który w momencie uruchamiania będzie automatycznie dodawał się do rejestru.

Projekt eureka.server

Wchodzimy na stronę Spring initializera i tworzymy projekt jak na poniższym zdjęciu. Poza metadanymi projektu i wersją Spring Boot-a niezwykle ważne jest dodanie zależności (dependency) spring-cloud-netflix Eureka Server. Po skonfigurowaniu pobieramy projekt (Generate) i rozpakowujemy go na dysku.
Java CheckedException
Dalej importujemy projekt jako Maven project do naszego IDE. Efekt importu jest taki jak poniżej. W celu zwiększenia czytelności zmieniliśmy nazwę wygenerowanej klasy z Application na EurekaServer.
Java CheckedException
Teraz musimy jeszcze włączyć funkcję rejestracji i udostępniania mikroserwisów (service discovery), realizowaną przez nasz projekt dzięki zależności spring-cloud-netflix Eureka Server (adnotacja @EnableEurekaServer pochodzi z pakietu org.springframework.cloud.netflix.eureka.server):
Java CheckedException
Kolejny krokiem jest dostarczenie konfiguracji polegającej na zdefiniowaniu portu, pod którym będzie dostępna nasza "usługa odkrywcza". Konfigurację dodajemy do pliku application.properties (/src/main/resources/application.properties):
Java CheckedException

Uruchomienie Eureka Service Registry

Uruchamiamy naszą usługę, uważnie obserwujemy konsolę i odnotowujemy, że na konsoli pojawił się...wyjątek:
Java CheckedException
Co ciekawe tak skonfigurowana usługa uruchomi się i będziemy mogli jej używać. Nie będzie to jednak w pełni satysfakcjonujące, dopóki nie rozwiążemy zaistniałego problemu. Wyjątek pojawia się, ponieważ nie istnieje żadna replikacja (replica node), do której nasza usługa mogłaby się podpiąć. Domyślnie eureka serwer oczekuje nodów do replikacji, ponieważ w środowisku produkcyjnym wymagana jest elastyczność i niezawodność. W takim środowisku usługa rejestru powinna być wielokrotnie replikowana.

Natomiast my nie potrzebujemy teraz omawiać replikacji, ponieważ chcemy jedynie uruchomić prosty rejestr usług w postaci jednej instancji, do której będzie mogło podpiąć się wiele mikroserwisów (a także wiele instancji każdego z nich).

Tak więc co robimy w tej sytuacji? Okazuje się, że możemy wyłączyć "dopytywanie się" eureki o nody replikacyjne. W tym celu dodajemy do application.properties własność eureka.client.fetch-registry, którą ustawiamy na false. W celu zwiększenia czytelności warto też wyłączyć opcję rejestracji serwera eureki w samym sobie - eureka.client.register-with-eureka.
Java CheckedException
Po wprowadzeniu tych zmian i ponownym uruchomieniu usługi, na konsoli nie pojawi się już żaden wyjątek. Oczekujemy na pełne uruchomienie rejestru, co zostanie nam oznajmione wpisem podobnym do poniższego:
Java CheckedException
Weryfikujemy, czy mamy dostęp do usługi poprzez wejście na stronę pod adresem url, który zdefiniowaliśmy wcześniej w pliku konfiguracyjnym application.properties:
Java CheckedException
Na uwagę z pewnością zasługuje fakt, że w sekcji Instances currently registered with Eureka nie mamy na tym etapie jeszcze żadnego zarejestrowanego mikroserwisu. Co ciekawe, gdybyśmy pozwolili na rejestrację serwisu Eureki (obecnie omawianego projektu), usuwając wpis eureka.client.register-with-eureka z application.properties, wówczas instancja tego serwisu pojawiłaby się tutaj jako zarejestrowana "sama w sobie":
Java CheckedException

Projekt eureka.microservice

Teraz przyszedł czas na stworzenie pierwszego mikroserwisu, który zarejestruje się a naszym rejestrze. Ponownie wchodzimy na stronę Spring initializera i tworzymy projekt, tyle że teraz nazywamy go inaczej - eureka.microservice. Poza metadanymi projektu i wersją Spring Boot-a niezwykle ważne jest dodanie zależności (dependency) spring-cloud-netflix Eureka Client (uwaga - poprzednio dodawaliśmy Eureka Server). Po skonfigurowaniu pobieramy projekt (Generate) i rozpakowujemy go na dysku.
Java CheckedException
Dalej importujemy projekt jako Maven project do naszego IDE. Efekt importu jest taki jak poniżej. W celu zwiększenia czytelności zmieniliśmy nazwę wygenerowanej klasy z Application na EurekaMicroservice.
Java CheckedException
Teraz musimy jeszcze przekształcić nasz projekt do postaci klienta Eureki, co jest realizowane dzięki zależności spring-cloud-netflix Eureka Discovery Client (adnotacja @EnableEurekaClient pochodzi z pakietu org.springframework.cloud.netflix.eureka):
Java CheckedException
Kolejny krokiem jest dostarczenie konfiguracji polegającej na zdefiniowaniu portu, pod którym będzie dostępny nasz mikroserwis. Konfigurację dodajemy do pliku application.properties (/src/main/resources/application.properties).
Appa Notka. Pamiętaj, że wprowadzamy usługę Eureki między innymi po to, by móc łatwo dodawać w przyszłości kolejne instancje danego mikroserwisu. W takiej sytuacji trudno byłoby zdefiniować porty na sztywno dla każdej instancji z osobna. Pozwalamy więc, aby numery portów były dobierane losowo.
Nie ustawiamy portu na sztywno. Zamiast tego podajemy wartość 0, która oznacza, że dla każdej kolejnej instancji porty będą dobierane losowo. W pliku dodajemy również nazwę naszej usługi (spring.application.name). To ona będzie widoczna na konsoli Eureki w kolumnie Application. Oprócz tego definiujemy własność eureka.instance.instance-id, która będzie unikalną nazwą generowaną dla każdej instancji. Wygenerowanie unikalnego identyfikatora jest zapewnione przez random:value:
Java CheckedException
Zanim uruchomimy w IntelliJ kilka instancji tego samego projektu mikroserwisu, należy umożliwić uruchamianie równoległe. Otwieramy okno Run/Debug Configurations i tam zaznaczamy checkbox Allow parallel run:
Java CheckedException
Java CheckedException

Uruchomienie i rejestracja kilku instancji mikroserwisu

Uruchamiamy kilka mikroserwisów. Właściwie wystarczą nawet już dwa, aby zaobserwować, co się dzieje. Pierwsza instancja startuje z losowo wybranym portem i rejestruje się na konsoli za pomocą randomowego identyfikatora:
Java CheckedException
Java CheckedException
Startujemy drugą instancję i ponownie widzimy nowy port oraz to, że kolejna instancja dodała się do rejestru Eureki:
Java CheckedException
Java CheckedException
Appa Notka. Dotarłe(a)ś do tego miejsca, realizując kolejne punkty w tym rozdziale? Gratulacje! Właśnie stworzyłe(a)ś swój pierwszy rejestr mikroserwisów na podstawie wzorca Service Discovery! W kolejnym rozdziale (dostępnym wkrótce) podłączymy się klientem do rejestru Eureki, która udostępni klientowi wybraną instancję mikroserwisu, w celu wykonania określonego zadania.

Self-preservation vs wyłączanie mikroserwisu

Na początku nauki Eureki w tym miejscu zwykle zaczyna się problem. Okazuje się, że wyłączając instancję mikroserwisu, ciągle widzimy ją dostępną na konsoli Eureki (tak jakby nadal działała). Spowodowane jest to tym, że domyślnie Eureka ma włączony tryb self-preservation, czyli chronienia usług przed usunięciem z rejestru, nawet jeśli nie ma z nimi kontaktu.

Usługa wysyła regularnie tzw. heartbeat do Eureki, dzięki czemu wiadomo, że dana usługa ciągle "żyje". Czasem jednak zdarza się, że takie sygnał nie przychodzi, co może oznaczać, iż usługa została niespodziewanie wyłączona. Natomiast Eureka "woli" jednak założyć, że mogą to być jedynie przejściowe trudności w komunikacji, na przykład kłopot z połączeniem sieciowym i z tego powodu nie wyrejestrowuje takiej usługi (dodatkowym kryterium jest liczba wyłączonych instancji danego mikroserwisu przekraczająca 85% wszystkich instancji).

O ile w środowisku produkcyjnym istotnym kryterium jest niezawodność w dłuższej perspektywie, o tyle w prostym przykładzie edukacyjnym tworzonym na własnej maszynie takie ustawienie może przeszkadzać. Można temu zaradzić ustawiając odpowiednią własność w pliku konfiguracyjnym application.properties (preservation) na wartość false. Przy okazji warto również zmienić czas uruchamiania joba sprawdzającego, które instancje są niedostępne i usuwającego (evict) te instancje z rejestru. Tak więc finalnie plik konfiguracyjny dla eureka.server będzie wyglądał tak:
Java CheckedException
Appa Notka. Uwaga. W momencie wyłączenia trybu ochrony konsola Eureki bedzie wyświetlała komunikat jak na poniższym zdjęciu. Pamiętając o tym, że pracujemy lokalnie i chcemy jedynie edukować się w temacie Eureki, nie musimy się tym przejmować. Oczywiście w środowisku produkcyjnym (a nawet i środowiskach pre-produkcyjnych należy opcję ochrony pozostawić włączoną).
Java CheckedException
W mikroserwisie rejestrującym się w Eurece także wprowadzimy pewne modyfikacje. Skrócimy czas wygaśnięcia dzierżawy oraz jej odświeżenia.
Java CheckedException
Teraz do momentu wyłączenia mikroserwisu po około 5 sekundach nastąpi wyrejestrowanie go z Eureki (zniknie z listy Instances currently registered with Eureka).
Autor: Kasia Kowolik
Data: 06 października 2020
Labele:Backend, Poziom średniozaawansowany, Java, Mikroserwisy, Spring, Spring Boot Linki
Spring Boot Initializr


https://github.com/javappa-coding/eureka-service-discovery

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy: stackshare
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .