JavaRush /Курси /Модуль 5. Spring /Лекція 225: Практика: оновлення конфігурацій на ходу

Лекція 225: Практика: оновлення конфігурацій на ходу

Модуль 5. Spring
Рівень 23 , Лекція 4
Відкрита

Ви дізналися, як налаштувати Spring Cloud Config Server, підключити його до сховища конфігурацій (наприклад, Git), а також як клієнтські мікросервіси можуть отримувати свої налаштування з централізованого сховища. Усе це чудово, але поки що проблема залишається: як оновити конфігурацію без перезапуску мікросервісу? Ну що, час брати цю фортецю «на ходу»! Сьогодні ми вивчимо, як динамічно оновлювати конфігурації за допомогою Spring Cloud Bus і подій. Так-так, усе буде відбуватись у режимі реального часу.


Проблеми з оновленням конфігурацій

Уявіть собі, що ви адміністратор додатку, який працює в розподіленій мікросервісній архітектурі. Ви хочете змінити одну маленьку налаштування, наприклад, URL зовнішнього API або рівень логування. Без динамічного оновлення вам потрібно:

  1. Спочатку змінити налаштування в конфігурації.
  2. Потім перезапустити всі затронуті мікросервіси.

Це звучить як робота, якої хочеться уникнути (піднімаємо руки ті, хто любить downtime!). Особливо в продакшені, де такі перезапуски можуть завдати болю користувачам і вашим колегам.

Рішення? Динамічне оновлення конфігурацій. Замість перезапуску сервісу ми можемо оновити конфігурації «на ходу», використовуючи інструменти, доступні в екосистемі Spring.


Підхід до динамічного оновлення конфігурацій

Навіщо потрібен Spring Cloud Bus?

Spring Cloud Bus — це інструмент, який зв'язує мікросервіси з використанням розподіленої системи обміну повідомленнями. Якщо сказати зовсім просто: він дозволяє «розповісти» іншим сервісам про те, що змінилися налаштування. Наприклад, при оновленні конфігурації Spring Cloud Bus може повідомити всі підключені мікросервіси про необхідність забрати свіжі налаштування з Spring Cloud Config Server.

Як працює процес?

  1. Ви оновлюєте файл конфігурації в Git (або іншому сховищі).
  2. На Config Server відбувається автоматичне підтягування змін.
  3. Spring Cloud Bus через брокер повідомлень (наприклад, RabbitMQ) повідомляє всі мікросервіси про зміну.
  4. Мікросервіси «підвантажують» оновлені налаштування локально.

Практика: оновлення конфігурацій на ходу

Що будемо використовувати:

  • 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, щоб вони оновили свої конфігурації.

Тестування

Спробуємо все протестувати:

  1. Переконайтесь, що всі сервіси запущені (RabbitMQ, Config Server, клієнтський мікросервіс).
  2. Змініть файл конфігурації в сховищі (наприклад, в Git) — змініть значення властивості custom.message.
  3. Виконайте команду curl -X POST http://localhost:8080/actuator/bus-refresh для оновлення конфігурацій.
  4. Запитайте http://localhost:8081/api/message (де 8081 — порт клієнта) до оновлення і після. Ви повинні побачити нове значення властивості.

Загальні зауваження

  • Якщо ви забули додати анотацію @RefreshScope, зміни не будуть застосовуватись «на ходу». Це одна з найпоширеніших помилок.
  • Spring Cloud Bus підтримує кілька брокерів повідомлень. RabbitMQ хороший для швидкого старту, але в більш складних системах ви можете використовувати Kafka для більшої надійності.
  • Переконайтесь, що ви додали bus-refresh у management.endpoints.web.exposure.include, інакше API оновлення не буде доступним.

Тепер ваш додаток динамічно оновлює конфігурації, а перезапуск мікросервісів більше не потрібен.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ