Сьогодні відповімо на це питання й навчимося застосовувати динамічне оновлення конфігурацій у реальному часі. Готуйте клавіатури!
Проблема статичних конфігурацій у мікросервісах
Уявіть, що ви адміністратор великого мікросервісного зоопарку (так-так, наша улюблена метафора). Наприклад, десятки мікросервісів залежать від одного й того самого параметра, скажімо, граничного ліміту на виконання операцій. Цей ліміт зберігається в централізованій конфігурації, але що відбувається, якщо його потрібно оновити?
- Ви змінюєте значення в сховищі (наприклад, у Git).
- Потім ви перезапускаєте кожен мікросервіс, щоб він підтягнув нове значення.
Це — справжній біль. Особливо якщо мікросервісів десятки чи сотні. Перезапуск — це не тільки незручно, а й може спричинити простої в системі. А якщо параметр часто змінюється? Тоді це вже не просто біль, а справжня катастрофа.
Щоб уникнути таких ситуацій, нам потрібно динамічне оновлення конфігурацій. Воно дозволяє застосовувати зміни «на льоту», без перезапуску мікросервісів. І тут підключається магія Spring Cloud Bus.
Spring Cloud Bus: основи
Spring Cloud Bus — інструмент для передачі повідомлень між мікросервісами з використанням брокера повідомлень, такого як RabbitMQ або Apache Kafka. Він дозволяє:
- Поширювати зміни конфігурацій між мікросервісами.
- Повідомляти компоненти системи про зміни.
- Реалізовувати event-driven підходи для керування налаштуваннями.
Приклад робочого сценарію
- Адміністратор змінює конфігурацію в Git (або іншому сховищі).
- Spring Cloud Config Server фіксує зміни і публікує подію про це в брокер повідомлень.
- Усі підписані мікросервіси отримують подію і автоматично оновлюють свої конфігурації.
Підходи до динамічного оновлення конфігурацій
Динамічне оновлення конфігурацій реалізується в Spring за допомогою кількох ключових елементів:
- Spring Cloud Bus для доставки подій про зміну конфігурації.
- Анотація
@RefreshScopeдля оновлення бінів, що залежать від конфігурації. - Виклик REST-методу для оновлення бінів — якщо хочете робити це вручну.
Пройдемося по кожному з них.
Spring Cloud Bus у дії
Spring Cloud Bus використовує брокери повідомлень (RabbitMQ, Kafka) для передачі подій. У нашому випадку ми будемо використовувати RabbitMQ (бо він легко інтегрується і широко застосовується).
Покроково це виглядає так:
- Spring Cloud Config Server публікує подію зміни конфігурації.
- Spring Cloud Bus пересилає цю подію підписникам (вашим мікросервісам).
- Підписники отримують подію і оновлюють свої налаштування в реальному часі.
Встановлення RabbitMQ — це окрема задача, але якщо ви ще не налаштували його, можна швидко розгорнути через Docker:
docker run -d --hostname rabbitmq --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
Використання анотації @RefreshScope
Анотація @RefreshScope — ваш головний інструмент для оновлення залежностей. Якщо у вас є бин, який бере значення з конфігурації, додавання @RefreshScope до цього біну забезпечить його оновлення при зміні цих значень.
Ось приклад:
@RestController
@RefreshScope
public class ConfigController {
@Value("${example.config.value}")
private String exampleConfig;
@GetMapping("/config")
public String getConfigValue() {
return this.exampleConfig;
}
}
Якщо параметр example.config.value буде змінено, бин автоматично підтягне оновлене значення після події оновлення конфігурації.
Зауважте, що @RefreshScope працює тільки з бінами, якими керує Spring. Якщо бин створено вручну (наприклад, через new), чудес не буде.
Виклик REST-методу для оновлення конфігурацій
Щоб мікросервіс зрозумів, що конфігурація оновилася, треба або дочекатися події Spring Cloud Bus, або вручну викликати метод /actuator/refresh. Цей метод потрібно включити в налаштуваннях:
management.endpoints.web.exposure.include=refresh
Для тестування можна використати curl:
curl -X POST http://localhost:8080/actuator/refresh
Після виклику /refresh всі біни з анотацією @RefreshScope оновляться, і разом з ними підтягнуться оновлені параметри.
Практика: налаштування Spring Cloud Bus
Давайте спробуємо налаштувати це на практиці. Ми створимо два мікросервіси (Config Server і Service), які будуть інтегровані з Spring Cloud Bus через RabbitMQ.
Крок 1: Налаштування Spring Cloud Config Server
Створіть новий Spring Boot проєкт (наприклад, через Spring Initializr) і додайте залежності:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
Увімкніть Config Server в коді:
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
Налаштуйте application.yml:
spring:
cloud:
config:
server:
git:
uri: https://your-repo-url
rabbitmq:
host: localhost
port: 5672
management:
endpoints:
web:
exposure:
include: "*"
Запустіть сервер і перевірте, що він працює.
Крок 2: Налаштування мікросервісу (client)
Створіть другий проєкт і додайте залежності:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
Налаштуйте bootstrap.yml для підключення до сервера:
spring:
application:
name: client-service
cloud:
config:
uri: http://localhost:8888
rabbitmq:
host: localhost
port: 5672
Додайте контролер з динамічною конфігурацією:
@RestController
@RefreshScope
public class TestController {
@Value("${example.config.value:default}")
private String configValue;
@GetMapping("/current-config")
public String getConfigValue() {
return configValue;
}
}
Крок 3: Перевірка динамічних оновлень
- Змініть конфігурацію в Git.
- Виконайте команду на Config Server:
curl -X POST http://localhost:8888/actuator/bus-refresh
Завдяки Spring Cloud Bus оновлені значення з'являться в мікросервісах автоматично.
Тепер у вас є робоча система, яка оновлює конфігурації в реальному часі. Використання Spring Cloud Bus значно спрощує керування налаштуваннями в розподілених системах, а ще дозволяє спати спокійно, знаючи, що перезапуск мікросервісів — це минуле століття.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ