Меня зовут Аксёнов Вячеслав, я старший бэкенд Java/Kotlin разработчик в крупном энтерпрайзе. Однажды я попал на проект, полный микросервисов, в котором за конфигурацию отвечала такая штука как Spring Cloud. Чтобы разобраться как именно это работает я исследовал и прикрутил этот диковенный элемент к одному своему пет проекту. И в этой статье я пошагово покажу как я это сделал. А если точнее - как настроить Spring Cloud сервер конфигурации.
Немного вводных данных
В наше время программирование переросло из чего-то магического и таинственного в довольно прозаичное занятие. Построение бэкенд приложения перестало напоминать построение монолита с местными прикладными решениями разной степени понятности и магии. Место постройки собственных велосипедов заняло использование уже готовых решений, подходящих для конкретных задач.
Для бэкеда крупных систем прямо сейчас в преимуществе используется Java/Kotlin в качестве основного языка программирования. А там где есть Java и энтрпрайз, там рука об руку идет Spring Framework. И так как строить монолиты сейчас не модно, выбор делается в сторону микросервисов. (мое мнение, что делать микросервисы совсем уж микро не стоит. Каждый сервис должен отвечать отдельной бизнес задаче. Но об этом я напишу в отдельной статье) И вот есть зоопарк сервисов - у каждого есть свои конфиги. И их нужно как-то менеджить. Вопрос - как это сделать?
Итак, какую проблему решает Spring Cloud? Представим, что у вас есть 5 приложений на Java/Spring, каждое при старте подгружает разные конфиги (пароли/адреса для базы, внешних апи и тд). Есть разные окружения - test, dev, prod, stage и тд. Spring Cloud позволяет хранить все конфигурации для разных приложений и разных окружений в одном месте.
Как же запускать?
Давайте разбираться как запускать эту систему на простом примере.
Есть несложное приложение на Spring, которое нужно научить ходить в клауд за конфигами. В моем случае этим является бот для логирования рабочего времени в телеграме, который я написал для личных целей - whid (what have I done). Но код открытый - кому интересно можете пользоваться моим, либо запустить для себя. На бизнес логику можно не обращать внимания, нас интересует только конфигурация для работы с Spring Cloud.
Настройка стороны сервиса:
Для этого в список зависимостей нужно добавить spring-cloud-starter-config и spring-cloud-starter-bootstrap:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.0.4</version>
</dependency>
Версии зависимостей можно брать актуальные с https://search.maven.org/
Пример в pom.xml: https://github.com/v-aksenov/whid-bot/blob/master/pom.xml#L35-L44
Также application.properties заменяется на bootstrap.yml, в которой нужно указать название текущего приложения и адрес для подключения к спринг клауду.
spring:
application:
name: whid-bot
config:
import: http://localhost:8888/
В данном случае название приложения whid-bot, а адрес для клауда http://localhost:8888/
Этого достаточно - стартеры для spring-cloud уже включают в себя нужные настройки, которые позволят сервису при запуске правильно понять, что используется spring cloud и правильно сходить к нему по настройкам, используемым в bootstrap.yml.
Настройка на стороне spring cloud:
Сам сервис конфигурации является отдельным спринг бут приложением. Для построения такого приложения требуются зависимость spring-cloud-config-server:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>3.0.5</version>
</dependency>
А также остальные зависимости, которые потребуются для работы spring boot приложения, как пример мой pom.xml: https://github.com/v-aksenov/spring-cloud-public/blob/master/pom.xml
Самое интересное начинается в конфигурации этого приложения.
spring.application.name=spring-cloud-name
server.port=8888
spring.cloud.config.server.git.uri=https://github.com/user/repo.git
spring.cloud.config.server.git.username=git_user
spring.cloud.config.server.git.password=*******
spring.cloud.config.server.git.searchPaths={application}
Что значит каждый параметр по порядку:
server.port=8888
- указывает порт, на котором будет запущен клауд. Если не конкретизироваться, то поднимется на дефолтном спринговом 8080
spring.cloud.config.server.git.uri=https://github.com/user/repo.git
- так как клауд удобнее всего использовать с конфигами, хранящимися в гите, то конечно ссылка на репозиторий с вашими конфигами, может быть как github, так gitlab, stash и тд.
spring.cloud.config.server.git.username=v-aksenov
spring.cloud.config.server.git.password=password
spring.cloud.config.server.git.username
, spring.cloud.config.server.git.password=password
- соответственно логин и пароль для подключения к репозиторию с конфигами.
spring.cloud.config.server.git.searchPaths={application}
- это указатель того, что для поиска параметров будет использоваться значение из spring.application.name у приложения, которое обращается к клауду.
Стоит держать в голове, что для разных профилей конфигурации нужно хранить в разных файлах. Например для профиля test - whid-bot-test.yml - для тестового окружения и для профиля prod - whid-bot-prod.yml для продового.
Примеры файлов конфигурации
Внутри моего приватного репозитория, где я храню конфиги для своих пет проектов лежит файлик с конфигурацией моего бота. Файл хранит в себе ровно то, что вы бы хранили в application.properties внутри основного приложения.
whid.yml:
bot:
username: whiddy_bot
token: *******
active: true
spring:
datasource:
url: jdbc:h2:file:./h2-data/whid-bot
username: *******
password: *******
driverClassName: org.h2.Driver
jpa:
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
hibernate.ddl-auto: update
h2:
console:
enabled: true
path: /h2-console
logging:
level:
root: INFO
file:
name: ./logs/whid-bot-logs.log
Итог
Всего вышеописанного достаточно для того, чтобы запустить собственный сервис конфигурации spring cloud и настроить ваш сервис для хождения за конфигами в него. Эта статья была написана как для тех, кто только разбирается с разными элементами инфраструктуры, которые позволяет наворотить Spring Framework, а также для лично меня, который сейчас разобрался в теме и в будущем обязательно забудет, но сможет посмотреть здесь.
Ссылка на проект кладуа
Надеюсь, статья была для вас полезна, буду рад вашим комментариям о том как кто-то из вас готовит архитектуру собственных пет проектов. Будет здорово, если каждый сможет узнать для себя что-то новое.
Всем чистого кода и хорошего дня :)
Фото обложки от: https://unsplash.com@pericakalimerica
Комментарии (13)
amarkevich
02.02.2022 19:24+2на мой взгляд Spring Cloud лишь усложняет архитектуру: для запуска приложения необходим работающий инстанс для получения конфигурации.
Как синхронизировать конфиг в процессе разработки, запускать тесты?
Логика настроек по итогу раздваивается. как обстоят дела с версионностью? (ок, вapplication
можно версию суффиксом).taluyev
02.02.2022 20:02За версионностью следит стстема контроля версий.
В тестах свои пропертис отдельные
идея такого подхода держать настройки в одном месте для разных инстансов
v-aksenov Автор
02.02.2022 20:04О да! Для маленьких проектов он однозначно заставит задуматься о тех вопросах, которые появляются во взрослых проектах. Пришлось протестировать различные схемы.
Для работы gitlab-ci тестов в изолированном окружении я понял, что проще всего будет хранить конфиги для тестов прямо в приложении. Но когда в твоем окружении есть доступ к всегда запущенному клауду, а параметров для разных контуров становится слишком много - вот тут клауд очень помогает!
По поводу версионности - сразу приходит на ум через суффикс в application, да. Но версионность - весьма редкая схема для конфигов все же, как мне кажется.
soir
02.02.2022 23:45+1Spring Cloud Config не нужно использовать на dev среде, т.е. на компьютере разработчика. На компьютере разработчика удобно хранить конфигурацию в файле application-dev.yml
Spring Cloud Config удобен для хранения настроек на серверах, в облаке. Версионность конфигурации реализуется подключение к нему репозитория в GIT в качестве источника данных
nbog
02.02.2022 19:57+3Хотел бы отметить, что то, что вы описали - это только Spring Cloud Config Server и его использование. Это очень небольшая часть Spring Cloud, куда входит куча всего.
Например service discovery, routing, load balancing, circuit breakers и прочие штуки от Netflix.
https://spring.io/projects/spring-cloud - вот тут много
v-aksenov Автор
02.02.2022 20:08+1Спасибо за такой полезный комментарий по делу. Действительно, в инфраструктуре Spring Cloud есть огромное количество интересных штук, которые кому-то могут облегчить жизнь.
В этой статье мне было интересно разобраться именно с частью конфигураций для своих пет проектов. Возможно, если увижу что можно у себя реализовать из остальных решений и мне зайдет, то тоже напишу статью :)nbog
02.02.2022 23:08+2Мы используем Spring Cloud уже несколько лет, 100+ микросервисов, много разных environments, включая production. Прошли от Unix -> PCF ->K8S, довольно стабильна эта часть Spring Cloud.
Ещё момент ... конфигурации (через spring profiles) можно хранить в ОДНОМ (для одного приложения) yaml файле. Это удобнее, ИМХО, для сопровождения. Кроме того можно сделать shared секцию, куда попадают общие настройки для все spring profiles.
v-aksenov Автор
03.02.2022 20:46Да, кстати. Поиск конфигурации идет по порядку service-profile.yml -> service.yml -> application.yml
Можно хранить общие для сервисов конфигри на самом низком уровне
chemtech
03.02.2022 07:59Спасибо за пост. Подскажите, пожалуйста, если знаете. Есть проект https://github.com/spring-petclinic/spring-petclinic-cloud
Я пытаюсь запустить spring-petclinic-cloud в kubernetes. Получаю ошибку
java.net.UnknownHostException: wavefront-proxy
Issue есть https://github.com/spring-petclinic/spring-petclinic-cloud/issues/39
Разработчики хотят обновить Spring Cloud и убрать Spring Cloud's bootstrap context.
Можете помочь с тестированием https://github.com/spring-petclinic/spring-petclinic-cloud/pull/43 ?
Спасибо.
dissdoc
Будет статья о том, как запустить Spring Boot приложение?
v-aksenov Автор
Думаю, что нет. Их и так достаточно :)