Вы узнали, как настроить 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 обновления не будет доступно.
Теперь ваше приложение динамически обновляет конфигурации, а перезапуск микросервисов больше не нужен.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ