Spring Cloud Config и Git. Хранение и распространение конфигураций приложений

—

от автора

Меня зовут Дмитрий Демченко. Я Java разработчик. На проектах я активно применяю новые технологии и подходы при разработке приложений, в том числе Spring Cloud и компоненты, входящие в общую экосистему этой технологии.

В данной статье я хочу поделиться с вами своим подходом к конфигурации Spring Boot приложений в облаке, где файлы конфигураций приложений находятся в Git репозитории, и который я применяю в работе и считаю одним из самых простых, удобных и легко поддерживаемых.

Плюсы и минусы данного подхода

Плюсы:

  1. Работает из коробки

  2. Легко настраивается

  3. Версионирование в Git

  4. Нет необходимости поднимать и обслуживать сторонние хранилища секретов

Минусы: по моему мнению очевидных минусов нет.

В рамках данной статьи я не буду затрагивать поднятие всего стека Spring Cloud, а расскажу лишь о примитивном применении Spring Cloud Config.

Выбор версии Java и Spring Boot

Многие проекты сейчас переписываются, а какие-то уже используют Java 17, поэтому и мы будем использовать Java 17 и Spring Boot 3.

Настройка Spring Cloud Config Server

Для начала нам нужно создать новый Spring Boot проект и подключить зависимость spring-cloud-config-server

Пример для Maven:

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-config-server</artifactId> </dependency>

Пример для Gradle:

implementation 'org.springframework.cloud:spring-cloud-config-server'

Далее нам нужно сконфигурировать сервис таким образом, чтобы он мог получать конфигурации наших Spring Boot приложений из нашего Git репозитория.

application.yml:

server:   port: 8888  spring:   application:     name: config-service   cloud:     config:       server:         git:           uri: git@github.com:dmitrii-demchenko/spring-boot-configs.git           username: username           password: password           default-label: main           search-paths: "{application}"

И добавить аннотацию @EnableConfigServer:

@SpringBootApplication @EnableConfigServer public class ConfigServiceApplication {      public static void main(String[] args) {         SpringApplication.run(ConfigServiceApplication.class, args);     }  }

Репозиторий с конфигурациями приложений

Все конфигурации находятся в своих папках, где имя папки является именем приложения.

Представим, что у нас есть три приложения: clients, orders и couriers. Исходя из этого, структура нашего репозитория с конфигурациями будет выглядеть так:

Структура репозитория

Структура репозитория

Здесь можно увидеть 3 папки с конкретными конфигурациями наших приложений, а так же 2 общих файла: application.yml и application-dev.yml

Дело в том, что Spring Cloud Config позволяет объединять конфигурацию таким образом, чтобы мы могли избавиться от «копипаста» и не повторять общие свойства в каждом конфигурационном файле. А постфикс -dev дает нам возможность задавать конфигурации для определенного профиля, с которым запускается приложение.

Посмотрим на содержимое этих файлов:

application.yml:

spring:   datasource:     driver-class-name: org.postgresql.Driver   jpa:     hibernate:       ddl-auto: validate     properties:       hibernate:         format_sql: true     show-sql: false   flyway:     enabled: true

application-dev.yml:

spring:   datasource:     hikari:       maximum-pool-size: 10       minimum-idle: 0

clients/application-dev.yml:

spring:   datasource:     url: jdbc:postgresql://localhost:5432/clients     username: username     password: password

orders/application-dev.yml:

spring:   datasource:     url: jdbc:postgresql://localhost:5432/orders     username: username     password: password

couriers/application-dev.yml:

spring:   datasource:     url: jdbc:postgresql://localhost:5432/couriers     username: username     password: password

Получается, что, например, для приложения clients конфигурация должна выглядеть следующим образом:

spring:   datasource:     url: jdbc:postgresql://localhost:5432/clients     username: username     password: password     driver-class-name: org.postgresql.Driver     hikari:       maximum-pool-size: 10       minimum-idle: 0   jpa:     hibernate:       ddl-auto: validate     properties:       hibernate:         format_sql: true     show-sql: false   flyway:     enabled: true

Запустим сервис конфигураций и проверим это.

Получение конфигурации (руками)

Выполнив запрос на эндпоинт http://localhost:8888/clients/dev получаем ответ:

{   "name": "clients",   "profiles": [     "dev"   ],   "label": null,   "version": "2e6f884042d117b7298baa10955e5f1d0bf8f6f2",   "state": null,   "propertySources": [     {       "name": "https://github.com/dmitrii-demchenko/spring-boot-configs.git/clients/application-dev.yml",       "source": {         "spring.datasource.url": "jdbc:postgresql://localhost:5432/clients",         "spring.datasource.username": "username",         "spring.datasource.password": "password"       }     },     {       "name": "https://github.com/dmitrii-demchenko/spring-boot-configs.git/application-dev.yml",       "source": {         "spring.datasource.hikari.maximum-pool-size": 10,         "spring.datasource.hikari.minimum-idle": 0       }     },     {       "name": "https://github.com/dmitrii-demchenko/spring-boot-configs.git/clients/application.yml",       "source": {         "spring.application.name": "clients"       }     },     {       "name": "https://github.com/dmitrii-demchenko/spring-boot-configs.git/application.yml",       "source": {         "spring.datasource.driver-class-name": "org.postgresql.Driver",         "spring.jpa.hibernate.ddl-auto": "validate",         "spring.jpa.properties.hibernate.format_sql": true,         "spring.jpa.show-sql": false,         "spring.flyway.enabled": true       }     }   ] }

Так убеждаемся, что приложение clients, запущенное с профилем dev получит необходимую конфигурацию.

Подключение сервиса конфигураций к приложению

Подключение зависимости spring-cloud-starter-config в приложении, которое будет получать конфигурацию от сервиса конфигураций.

Пример для Maven:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>

Пример для Gradle:

implementation 'org.springframework.cloud:spring-cloud-starter-config'

Осталось описать application.yml:

spring:   application:     name: clients  ---  spring:   config:     activate:       on-profile: dev     import: optional:configserver:http://localhost:8888   cloud:     config:       fail-fast: true

Пройдемся по основным свойствам.

Во-первых, нужно задать имя приложения таким образом, чтобы оно совпадало с именем папки в репозитории с конфигурациями. Это свойство spring.application.name

Во-вторых, нужно указать приложению откуда получать конфигурации, за это отвечает свойство spring.config.import

Так же, в своем примере я добавил следующие свойства:

  1. spring.config.activte.on-profile: dev для того, чтобы сказать приложению при запуске с каким профилем получать конфигурации. Можно указать множество профилей.

  2. spring.cloud.config.fail-fast: true этот параметр задан для того, чтобы, если приложению не удалось получить конфигурацию, оно не будет запущено. Такой режим рекомендуется использовать в реальных проектах.

Запустим приложение с профилем dev и убедимся, что оно успешно получило конфигурацию от нашего сервиса конфигураций:

Но что делать, если нужно приложение запустить локально и без получения конфигураций от сервиса конфигураций?

Как пример, которым я пользуюсь, это добавить файл application-local.yml и запускать приложение с профилем local:

spring:   cloud:     config:       enabled: false

Резюме

Можно легко и быстро развернуть готовое и централизованное решение, которое будет сообщать приложениям в облаке их конфигурации. Это вполне рабочий вариант, который вы можете применять в своей работе.

Ссылки

Официальная документация Spring Cloud Config


ссылка на оригинал статьи https://habr.com/ru/articles/764402/