Легке керування конфігураціями мікросервісів за допомогою microconfig.io

Однією з основних проблем при розробці та подальшій експлуатації мікросервісів є грамотне та акуратне налаштування їх інстансів. У цьому, як на мене, може допомогти новий фреймворк microconfig.io. Він дозволяє досить елегантно вирішити деякі рутинні завдання налаштування програм.

Якщо у вас багато мікросервісів, і кожен з них поставляється разом зі своїм файлом/файлами налаштувань, то велика ймовірність зробити помилку в одному з них, яку без належної вправності та системи логування може бути дуже не просто відловити. Основне завдання, яке перед собою ставить фреймворк — звести до мінімуму параметри інстансу, що дублюють, тим самим зменшити ймовірність додавання помилки.

Розглянемо з прикладу. Припустимо, що є простий додаток з файлом конфігурації ямл. Це може бути будь-який мікросервіс будь-якою мовою. Подивимося, як фреймворк можна застосувати до цього сервісу.

Але перш, для більшої зручності створимо порожній проект в Idea IDE, попередньо встановивши в ній плагін microconfig.io:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

Налаштовуємо конфігурацію запуску плагіна, можна використовувати конфігурацію за замовчуванням як на скріншоті зверху.

Наш сервіс називається order, тоді у новому проекті створимо подібну структуру:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

У папку з ім'ям сервісу поміщаємо конфігураційний файл — application.yaml. Усі мікросервіси запускаються в якомусь оточенні, так що, крім створення конфіга самого сервісу, необхідно описати саме середовище: для цього створимо папку envs і додамо до неї файл з ім'ям нашого робочого середовища. Таким чином, фреймворк створить конфігураційні файли для сервісів у середовищі DEV, оскільки в налаштуваннях у плагіні встановлено саме цей параметр.

Структура файлу dev.yaml буде досить проста:

mainorder:
    components:
         - order

Фреймворк працює з конфігураціями, об'єднаними у групи. Для нашого сервісу виберемо ім'я для групи mainorder. Фреймворк знаходить кожну таку групу додатків у файлі оточення і створює для всіх конфігурації, які знаходить у відповідних папках.

У самому файлі налаштувань сервісу порядок вкажемо поки що лише один параметр:

spring.application.name: order

Тепер запустимо плагін, і він згенерує нам потрібну конфігурацію нашого сервісу за вказаним у властивостях шляху:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

Можна обійтися і без встановлення плагіна, просто завантаживши дистрибутив фреймворку та запустивши його з командного рядка.
Таке рішення підійде для використання на сервері збирання.

Фреймворк чудово розуміє власність синтаксис, тобто звичайні property файли, які можна використовувати разом у ямл конфігураціями.

Додамо ще один сервіс оплата і ускладнимо одночасно існуючий.
В порядок:

eureka:
 instance.preferIpAddress: true
 client:
   serviceUrl:
     defaultZone: http://192.89.89.111:6782/eureka/
server.port: 9999
spring.application.name: order
db.url: 192.168.0.100

В оплата:

eureka:
 instance.preferIpAddress: true
 client:
   serviceUrl:
     defaultZone: http://192.89.89.111:6782/eureka/
server.port: 9998
spring.application.name: payments
db.url: 192.168.0.100

Основна проблема цих конфігурацій - наявність великої кількості копіпаста в налаштуваннях сервісів. Подивимося, як фреймворк допоможе її позбутися. Почнемо з очевидною — наявність конфігурації еврика в описі кожного мікросервісу. Створимо новий каталог із файлом налаштувань і додамо до неї нову конфігурацію:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

І до кожного з наших проектів тепер додамо рядок #include eureka.

Фреймворк автоматично знайде конфігурацію eureka і скопіює її в конфігураційні файли сервісів, при цьому окрема конфігурація eureka не буде створена, тому що ми не вкажемо її у файлі середовища dev.yaml. Сервіс порядок:

#include eureka
server.port: 9999
spring.application.name: order
db.url: 192.168.0.100

Також ми можемо винести установки бази даних в окрему конфігурацію, змінивши рядок імпорту на #include eureka, oracle.

Кожна зміна при перегенерації конфігураційних файлів фреймворк відстежує та поміщає у спеціальний файл поряд з основним файлом конфігурації. Запис у його лозі виглядає так: “Stored 1 property changes to order/diff-application.yaml”. Це дозволяє швидко виявити зміни у великих файлах конфігурації.

Винесення загальних частин конфігурації дозволяє позбавитися безлічі непотрібного копіпаста, але не дозволяє гнучко створювати конфігурацію для різних середовищ - ендпоінти наших сервісів єдині і захардшкірені, це погано. Спробуймо це прибрати.

Хорошим рішенням буде тримати всі ендпоінти в одній конфігурації, на яку могли б посилатися інші. Для цього у фреймворк впроваджено підтримку плейсхолдерів. Ось як зміниться файл конфігурації еврика:

 client:
   serviceUrl:
     defaultZone: http://${endpoints@eurekaip}:6782/eureka/

Тепер побачимо, як працює цей плейсхолдер. Система знаходить компонент з ім'ям кінцеві точки і шукає в ньому значення eurekaip, після чого підставляє нашу конфігурацію. Але як бути з різними середовищами? Для цього створимо файл налаштувань у кінцеві точки наступного виду application.dev.yaml. Фреймворк самостійно, по розширенню файлу приймає рішення до якого середовища належить дана конфігурація і підвантажує її:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

Вміст dev файлу:

eurekaip: 192.89.89.111
dbip: 192.168.0.100

Таку саму конфігурацію ми можемо створити і для портів наших сервісів:

server.port: ${ports@order}.

Всі важливі параметри знаходяться в одному місці, тим самим зменшується ймовірність помилки через розкидані параметри файлів конфігурації.

Фреймворк надає безліч вже готових плейсхолдерів, наприклад, можна отримати назву директорії, в якій знаходиться файл конфігурації та присвоїти його:

#include eureka, oracle
server.port: ${ports@order}
spring.application.name: ${this@name}

Завдяки цьому, не потрібно додатково вказувати ім'я додатка в конфігурації і його можна також винести в загальний модуль, наприклад, у ту саму eureka:

client:
   serviceUrl:
     defaultZone: http://${endpoints@eurekaip}:6782/eureka/
 spring.application.name: ${this@name}

Файл конфігурації порядок скоротиться до одного рядка:

#include eureka, oracle
server.port: ${ports@order}

Якщо будь-яке налаштування з батьківської конфігурації нам не потрібне ми можемо вказати її в нашій конфігурації і саме вона буде застосована при генерації. Тобто, якщо з якоїсь причини нам потрібне унікальне ім'я для сервісу order, просто залишимо параметр spring.application.name.

Допустимо, до сервісу необхідно додати кастомізовані налаштування логування, які зберігаються в окремому файлі, наприклад, logback.xml. Створимо для нього окрему групу налаштувань:

Легке керування конфігураціями мікросервісів за допомогою microconfig.io

У базовій конфігурації вкажемо фреймворку, куди розміщувати потрібний нам файл налаштувань логування за допомогою плейсхолдера @ConfigDir:

microconfig.template.logback.fromFile: ${logback@configDir}/logback.xml

У файлі logback.xml налаштовуємо стандартні апендери, які також у свою чергу можуть містити плейсхолдери, які фреймворк змінить під час генерації конфігів, наприклад:

<file>logs/${this@name}.log</file>

Додаючи в конфігурації сервісів імпорт реєстрація, ми автоматично отримуємо налаштоване логування для кожного сервісу:

#include eureka, oracle, logback
server.port: ${ports@order}

Настав час більш детально ознайомиться з усіма доступними плейсхолдерами фреймворку:

${this@env} - Повертає ім'я поточного середовища.
${…@name} - Повертає ім'я компонента.
${…@configDir} - Повертає повний шлях до каталогу config компонента.
${…@resultDir} - Повертає повний шлях до каталогу призначення компонента (отримані файли будуть поміщені в цей каталог).
${this@configRoot} - Повертає повний шлях до кореневого каталогу сховища конфігурацій.

Також система дозволяє отримати змінні середовища, наприклад, шлях до java:
${env@JAVA_HOME}
Або, оскільки фреймворк написано на JAVA, можемо отримати системні змінні аналогічні виклику System::getProperty за допомогою конструкції такого виду:
${[захищено електронною поштою]}
Варто згадати про підтримку мови розширень Весна ЕЛ. У конфігурації застосовні такі вирази:

connection.timeoutInMs: #{5 * 60 * 1000}
datasource.maximum-pool-size: #{${[email protected]} + 10} 

і можна використовувати локальні змінні в конфігураційних файлах за допомогою виразу #вар:

#var feedRoot: ${[email protected]}/feed
folder:
 root: ${this@feedRoot}
 success: ${this@feedRoot}/archive
 error: ${this@feedRoot}/error

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

Якщо вас зацікавив цей фреймворк, то рекомендую відвідати його офіційну сторінку та ознайомитись з повною документацією, або покопатися у вихідниках тут.

Джерело: habr.com

Додати коментар або відгук