Під час запуску Spring-програм у хмарі не обійтися без Spring Cloud. Він помітно спрощує та пришвидшує всі операції. Інструменти Spring Cloud дозволяють легко створювати та розгортати у хмарі застосунки. Також є можливості для управління Discovery Server, менеджменту конфігурацій, роутингів.
Хоча модулі Spring Cloud призначені для застосунків на мікросервісній архітектурі, деякі з них можна використовувати у звичайних спрингових програмах. Наприклад, таким є сервер конфігурацій.
Натепер існує понад 30 модулів для Spring Cloud. Вони охоплюють буквально всі напрями роботи у хмарі. Якщо у вас виникла якась проблема, пов'язана з розгортанням застосунку у хмарі, то, ймовірно, її можна вирішити за допомогою одного з цих модулів:
Модулі Spring Cloud
Discovery Server — що це?
Рідко у хмарі запускається одна копія кожного з пов'язаних мікросервісів. Щоб забезпечити стабільність програми та підвищити її продуктивність, варто розгорнути кілька інстансів. Однак тоді буде складно вирішити, як краще організувати спільний доступ кількох мікросервісів. Не зрозуміло, як їм дізнаватися про актуальний шлях один до одного, як балансувати навантаження, як керувати помилками.
Одне з поширених рішень — розмістити мікросервіси під балансувальник навантаження. Це дозволить створити єдину для всіх копій DNS-адресу, через яку надходитимуть звернення та будуватимуться зв'язки. Також ви зможете налаштувати балансування навантаження та хелсчеки, щоб керувати падіннями мікросервісів.
Зауважу, що балансувальники мають кілька обмежень. По-перше, такі інструменти дорогі. По-друге, їх треба створювати окремо для кожного окремого типу мікросервісів. У такому разі у великих проєктах можуть знадобитися сотні таких тулзів. Якщо йдеться, наприклад, про Internal Cloud, то все це стає занадто складним і врешті непотрібним.
Spring Cloud
На допомогу приходить Discovery Server. По суті, це спеціальна нода в клауді, яка реєструє всі мікросервіси всередині хмари. Мікросервіс надсилає запит до Discovery Server, а той заносить його до свого реєстру. Коли до цього мікросервісу захоче звернутися інший мікросервіс, все станеться автоматично. Нам навіть не треба знати шлях у застосунку до початкового сервісу. З реєстром у Discovery Server ми можемо легко зматчити відповідні ім'я та шлях. Це можливо завдяки зв'язці, що описує шлях до сервісу, який він сам і надав під час реєстрації.
З Discovery Server балансування навантаження переходить від провайдера до клієнта. В результаті ви можете обрати будь-який інструмент для балансування навантаження і налаштувати в ньому будь-які правила без огляду на обмеження провайдера. Також Discovery Server допомагає кешувати шляхи. У разі виклику мікросервісу із закешованим шляхом не потрібно звертатися до реєстру. Так ви зекономите кілька мілісекунд, а це важливо за умови жорсткого latency.
Spring Cloud
Як працювати з Discovery Server
Один із прикладів Discovery Server — Spring Cloud Eureka. Інструмент розробили у Netflix, та згодом він став opensource-продуктом. Eureka має альтернативи, що підтримуються в Spring Cloud: Apache Zookeeper, Consul та Kubernetes для Docker.
Для застосування будь-якого Discovery Server у Spring Cloud треба створити проєкт із використанням серверної залежності. Далі включити цей сервер завдяки анотації, а потім задізейблити клієнтський модуль за допомогою проперті у конфігурації.
У Spring Boot програм за замовчуванням є клієнтський проперті для підключення до цього сервера. І якщо не задізейблити все на сервері, він намагатиметься підключитися до самого себе. На стороні клієнта ще простіше — варто лише додати клієнтську залежність. Для зручності також можна прописати параметр зі спеціальним ID цієї ноди. Тоді за наявності Eureka Server на локальному хості за портом 8761 підключення буде автоматичним.
Spring Boot
Розглянемо для прикладу найпростіший Eureka Server.
Eureka Server
У ньому є стандартна залежність із netflix-eureka-server.
Інструменти Spring Cloud: практичний ґайд для розробників
Майже в кожен застосунок додано актуатор. Це дозволяє трекати стан ноди.
Також тут є лише один стартовий клас main.
Вся магія створюється конфігурацією та однією залежністю. Вона вказує, що ми хочемо підняти сервер на порту 8761, що це Discovery Server і відключення всіх клієнтських проперті.
Також є застосунок, middle client. Він буде підключатися до сервера та реєструвати себе. Це звичайний Spring WebClient, який повертає просте ping-повідомлення з ім'ям програми та ID її інстансу.
У цьому випадку мені довелося витягнути залежність EurekaClient, щоб показати ID кожної ноди. Далі я запущу три копії цього інстансу в окремих консолях.
У параметрах у мене вказаний порт 0, тому порти будуть різні, і нам не треба буде самостійно мапити їх.
Також кожен інстанс має свій ID.
Викликати цей middle client без використання URL буде інший застосунок. Він є стороннім HTTP-клієнтом.
У цього клієнта є залежність у вигляді Eureka-клієнту.
В обох випадках є найпростіший метод ping, який буде викликатися віддалено.
Цей метод робитиме remote call на middle client.
При цьому в URL використовується назва самого клієнта.
У результаті можна передавати назву потрібних сервісів і використовувати їх в URL для віддаленого виклику без повного шляху до сервісу.
Запущений Eureka Server можна отримати за портом 8761. У Spring для цього клієнта є повноцінний UI, який показує стан хмари. Тут можна знайти багато корисної інформації. Це можуть бути технічні дані. Наприклад, час сервера, аптайм, кількість пам'яті тощо.
Eureka Server
В окремій таблиці відображаються інстанси. У нас вже зареєструвалося три копії middle client.
Можна перейти на актуатор або викликати його метод ping, який покаже ID клієнта. Цей номер є випадковим для кожного мікросервісу та не повинен повторюватися.
Також після запуску та реєстрації тут з'являється HTTP-клієнт.
При виклику методу ping на цьому кордонному HTTP-клієнті ми будемо отримувати відповідь від іншого клієнта без використання URL, тільки на основі імені.
Ми запустили три копії. Балансування навантаження між ними виконується на стороні клієнта, це описується інструкцією LoadBalance. Завдяки цьому відбувається послідовний виклик кожного сервісу, доступний із Discovery Server.
ID сервісу щоразу змінюється. Тобто балансування працює лише за рахунок однієї анотації. При вимкненні кожного застосунку в Discovery Server надходитиме повідомлення про падіння і можливість відключення.
Описаний приклад — найпростіший. І балансування, і керування розумними шляхами ви можете кастомізувати під свої завдання.
Навіщо потрібні репліки Eureka
Discovery Server є центральною ланкою інфраструктури, тому цей інструмент повинен мати високий запас міцності. При падінні Discovery Server клієнти можуть деякий час прожити і без нього, якщо вони робили якісь запити і на стороні клієнта є кешування. Однак усі нові копії під час спроби реєстрації будуть періодично видавати повідомлення на кшталт «Я не можу підключитися». Тому для Discovery Server теж вигадали реплікацію. В Eureka вона майже нативна та працює завдяки тому, що сам сервер стає клієнтом.
Розглянемо роботу реплікації. На ілюстрації — застосунок з одним main-класом. Це і є Discovery Server.
Для створення реплікації на цьому сервері потрібно вказати в client property інший Discovery Server.
У моєму прикладі трохи більше проперті. Якщо кілька копій намагаються зареєструватися одна в одній, то їм для коректного виконання цієї процедури потрібен певний threshold.
У нас є дві конфігурації, peer1 та peer2, які працюють на різних портах. Не можна запустити репліки на одній локальній машині, тому що Eureka прив'язується до назви хоста. Доводиться йти на хитрощі і прописувати hostname в DNS-параметрах hosts в папці C:/Windows/System32/drivers/etc/. Інакше це все просто не запрацює.
Запускаємо peer1…
Завдяки наявності двох реплік можна показати, як вони взаємодіють одна з одною. Запускати peer2 краще одночасно з першим.
Якщо пауза між стартами буде занадто великою, то перша репліка не зможе знайти другу і видаватиме помилку.
Саме з цієї причини я виставив threshold у 30 секунд. Так репліки встигнуть синхронізуватись.
Після запуску одного з інстансів на порті 8081 буде видно репліку 1. У реєстрі Discovery Server вона представлена у двох примірниках:
Також вона показує, що має репліку на порті 8082.
При відкритті цього порту ситуація стає прямо протилежною — там видно репліку на 8081.
Тож у разі падіння Discovery Server така проста реплікація зробить ваш застосунок та хмарну інфраструктуру надійнішою.