Ви дізналися, як налаштувати Spring Cloud Config Server, підключити його до сховища конфігурацій (наприклад, Git), а також як клієнтські мікросервіси можуть отримувати свої налаштування з централізованого сховища. Усе це чудово, але поки що проблема залишається: як оновити конфігурацію без перезапуску мікросервісу? Ну що, час брати цю фортецю «на ходу»! Сьогодні ми вивчимо, як динамічно оновлювати конфігурації за допомогою Spring Cloud Bus і подій. Так-так, усе буде відбуватись у режимі реального часу.
Проблеми з оновленням конфігурацій
Уявіть собі, що ви адміністратор додатку, який працює в розподіленій мікросервісній архітектурі. Ви хочете змінити одну маленьку налаштування, наприклад, URL зовнішнього API або рівень логування. Без динамічного оновлення вам потрібно:
- Спочатку змінити налаштування в конфігурації.
- Потім перезапустити всі затронуті мікросервіси.
Це звучить як робота, якої хочеться уникнути (піднімаємо руки ті, хто любить downtime!). Особливо в продакшені, де такі перезапуски можуть завдати болю користувачам і вашим колегам.
Рішення? Динамічне оновлення конфігурацій. Замість перезапуску сервісу ми можемо оновити конфігурації «на ходу», використовуючи інструменти, доступні в екосистемі Spring.
Підхід до динамічного оновлення конфігурацій
Навіщо потрібен Spring Cloud Bus?
Spring Cloud Bus — це інструмент, який зв'язує мікросервіси з використанням розподіленої системи обміну повідомленнями. Якщо сказати зовсім просто: він дозволяє «розповісти» іншим сервісам про те, що змінилися налаштування. Наприклад, при оновленні конфігурації Spring Cloud Bus може повідомити всі підключені мікросервіси про необхідність забрати свіжі налаштування з Spring Cloud Config Server.
Як працює процес?
- Ви оновлюєте файл конфігурації в Git (або іншому сховищі).
- На Config Server відбувається автоматичне підтягування змін.
- Spring Cloud Bus через брокер повідомлень (наприклад, RabbitMQ) повідомляє всі мікросервіси про зміну.
- Мікросервіси «підвантажують» оновлені налаштування локально.
Практика: оновлення конфігурацій на ходу
Що будемо використовувати:
- Spring Boot для мікросервісів.
- Spring Cloud Config для централізованого керування конфігураціями.
- Spring Cloud Bus для повідомлень.
- RabbitMQ як брокер повідомлень.
Ви могли б використати інший брокер, наприклад Apache Kafka, але для нашого прикладу оберемо RabbitMQ, оскільки він простий у налаштуванні і сумісний з Spring Cloud Bus.
Кроки реалізації
Крок 1: Налаштування RabbitMQ
Перш за все встановимо RabbitMQ. Якщо у вас він вже встановлений і працює, можете переходити далі.
Для встановлення в Docker використайте:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
- Інтерфейс керування RabbitMQ доступний за адресою:
http://localhost:15672/ - Логін:
guest, пароль:guest.
Крок 2: Налаштування Spring Cloud Config Server
Ми будемо використовувати вже створений Config Server з попередніх лекцій. Додайте наступну залежність в pom.xml вашого Config Server:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Ця залежність підключає Spring Cloud Bus з використанням RabbitMQ.
Тепер додайте в файл application.yml Config Server наступні налаштування:
spring:
cloud:
bus:
enabled: true
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
Таким чином, Config Server буде пов'язаний з RabbitMQ для публікації подій в шину.
Крок 3: Налаштування клієнтського мікросервісу
У клієнтському мікросервісі також додайте залежність spring-cloud-starter-bus-amqp в pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
І налаштуйте підключення до RabbitMQ, додавши у application.yml клієнта:
spring:
cloud:
config:
uri: http://localhost:8888 # URL Config Server
bus:
enabled: true
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: refresh, bus-refresh
Зверніть увагу на management.endpoints.web.exposure.include. Цей рядок дозволяє нам викликати точки входу /actuator/refresh і /actuator/bus-refresh.
Крок 4: Використання анотації @RefreshScope
Тепер давайте змінимо поведінку нашого сервісу так, щоб він динамічно оновлював налаштування. Для цього використаємо анотацію @RefreshScope.
Приклад коду:
@RestController
@RequestMapping("/api")
public class MyController {
@Value("${custom.message:Default message}") // Зв'язуємося з конфігурацією
private String message;
@GetMapping("/message")
public String getMessage() {
return message;
}
}
Додайте анотацію @RefreshScope на рівні класу:
@RefreshScope
@RestController
@RequestMapping("/api")
public class MyController {
// інший код без змін
}
Тепер, кожного разу, коли конфігурація оновлюється, поле message буде автоматично перезавантажено.
Крок 5: Оновлення конфігурації
Коли ви робите зміни в конфігурації (наприклад, файл в Git), викликайте наступний API на сервері:
curl -X POST http://localhost:8080/actuator/bus-refresh
Де 8080 — це порт Config Server.
Ця дія відправить повідомлення всім клієнтам, підписаним через Spring Cloud Bus, щоб вони оновили свої конфігурації.
Тестування
Спробуємо все протестувати:
- Переконайтесь, що всі сервіси запущені (RabbitMQ, Config Server, клієнтський мікросервіс).
- Змініть файл конфігурації в сховищі (наприклад, в Git) — змініть значення властивості
custom.message. - Виконайте команду
curl -X POST http://localhost:8080/actuator/bus-refreshдля оновлення конфігурацій. - Запитайте
http://localhost:8081/api/message(де8081— порт клієнта) до оновлення і після. Ви повинні побачити нове значення властивості.
Загальні зауваження
- Якщо ви забули додати анотацію
@RefreshScope, зміни не будуть застосовуватись «на ходу». Це одна з найпоширеніших помилок. - Spring Cloud Bus підтримує кілька брокерів повідомлень. RabbitMQ хороший для швидкого старту, але в більш складних системах ви можете використовувати Kafka для більшої надійності.
- Переконайтесь, що ви додали
bus-refreshуmanagement.endpoints.web.exposure.include, інакше API оновлення не буде доступним.
Тепер ваш додаток динамічно оновлює конфігурації, а перезапуск мікросервісів більше не потрібен.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ