Snadná správa konfigurací mikroservisů pomocí microconfig.io

Jedním z hlavních problémů při vývoji a následném provozování mikroservisů je správné a pečlivé nastavení jejich instancí. V tom, podle mého názoru, může pomoci nový rámec microconfig.io. Umožňuje poměrně elegantně vyřešit některé rutinní úkoly nastavení aplikací.

Pokud máte hodně mikroservisů a každý z nich přichází se svým souborem/soubory nastavení, je pravděpodobnost chyby v jednom z nich velmi vysoká, kterou bez potřebné zručnosti a systému logování může být obtížné odchytit. Hlavním úkolem, který si rámec klade, je minimalizovat duplicitní parametry nastavení instance, čímž se sníží pravděpodobnost vzniku chyby.

Podívejme se na příklad. Předpokládejme, že existuje jednoduchá aplikace se souborem konfigurace yaml. Může to být jakýkoli mikroservis v jakémkoli jazyce. Podívejme se, jak je rámec možné aplikovat na tuto službu.

Ale nejprve, pro větší pohodlí, vytvořme prázdný projekt v IDE Idea, předtím nainstalujeme plugin microconfig.io:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

Nastavujeme konfiguraci spuštění pluginu, můžeme použít konfiguraci výchozí, jak je na snímku obrazovky nahoře.

Naše služba se nazývá order, takže v novém projektu vytvoříme podobnou strukturu:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

Do složky podle názvu služby umístíme soubor konfigurace — application.yaml. Všechny mikroservisy se spouštějí v nějakém prostředí, takže kromě vytvoření konfigu samotné služby je nutné popsat samo prostředí: k tomu vytvoříme složku envs a přidáme do ní soubor s názvem našeho pracovní prostředí. Tímto způsobem rámec vytvoří konfigurační soubory pro služby v prostředí dev, protože v nastaveních pluginu je nastaven právě tento parametr.

Struktura souboru dev.yaml bude docela jednoduchá:

mainorder:
    components:
         - order

Rámec pracuje s konfiguracemi, které jsou seskupeny do skupin. Pro naši službu vybereme název pro skupinu mainorder. Rámec najde každou takovou skupinu aplikací v souboru prostředí a vytvoří pro ně všechny konfigurace, které nalezne v odpovídajících složkách.

Ve vlastním souboru nastavení služby order zatím uvedeme pouze jeden parametr:

spring.application.name: order

Nyní spustíme plugin a on nám vygeneruje potřebnou konfiguraci naší služby podle uvedeného v properties cesty:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

Můžeme se obejít a bez instalace pluginu, stačí stáhnout distribuci frameworku a spustit jej z příkazového řádku.
Toto řešení bude vyhovovat pro použití na serveru sestavení.

Je třeba poznamenat, že framework skvěle rozumí property syntaxi, což jsou běžné soubory property, které lze používat společně s yaml konfiguracemi.

Přidáme další službu payment a zároveň zkomplikujeme tu stávající.
V order:

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

V payment:

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

Hlavním problémem těchto konfigurací je velké množství kopírování a vkládání v nastavení služeb. Podívejme se, jak nám framework pomůže se jí zbavit. Začněme tou nejzřejmější — přítomností konfigurace eureka v popisu každého mikroslužby. Vytvoříme nový adresář s konfiguračním souborem a přidáme do něj novou konfiguraci:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

A do každého z našich projektů nyní přidáme řádek #include eureka.

Framework automaticky najde konfiguraci eureka a zkopíruje ji do konfiguračních souborů služeb, přičemž samostatná konfigurace eureka nebude vytvořena, protože ji neuvedeme v konfiguračním souboru dev.yaml. Služba order:

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

Také můžeme vyjmout nastavení databáze do samostatné konfigurace, pokud změníme řádek importu na #include eureka, oracle.

Je třeba poznamenat, že každou změnu při regeneraci konfiguračních souborů framework sleduje a zapisuje do speciálního souboru vedle hlavního konfiguračního souboru. Záznam v jeho logu vypadá takto: “Uloženo 1 změna vlastnosti do order/diff-application.yaml”. To umožňuje rychle odhalit změny ve velkých konfiguračních souborech.

Vytahování společných částí konfigurace umožňuje zbavit se zbytečného kopírování a vkládání, ale neumožňuje flexibilně vytvářet konfiguraci pro různé prostředí — koncové body našich služeb jsou jedinečné a hardcodované, což je problém. Pokusíme se to odstranit.

Dobré řešení by bylo uchovávat všechny koncové body v nějaké jediné konfiguraci, na kterou by ostatní mohli odkazovat. Pro tento účel framework implementoval podporu pro placeholdery. Takto se změní konfigurační soubor eureka:

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

Nyní se podívejme, jak funguje tento placeholder. Systém najde komponentu s názvem endpoints a hledá v něm hodnotu eurekaip, po čemž se vloží do naší konfigurace. Co si ale počít s různými prostředími? K tomu vytvoříme konfigurační soubor v endpoints následující podobě application.dev.yaml. Framework sám o sobě podle přípony souboru rozhoduje, k jakému prostředí se daná konfigurace vztahuje, a načte ji:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

Obsah dev souboru:

eurekaip: 192.89.89.111
dbip: 192.168.0.100

Podobnou konfiguraci můžeme vytvořit i pro porty našich služeb:

server.port: ${ports@order}.

Všechny důležité nastavení se nacházejí na jednom místě, čímž se snižuje pravděpodobnost chyby kvůli roztrženým parametrům v konfiguračních souborech.

Framework poskytuje mnoho již hotových placeholderů, například, lze získat název adresáře, ve kterém se nachází konfigurační soubor, a přiřadit ho:

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

Díky tomu není nutné dodatečně uvádět název aplikace v konfiguraci, a může se také vyvést do společného modulu, například do stejného eureka:

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

Konfigurační soubor order se zkrátí na jeden řádek:

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

Pokud některé nastavení z rodičovské konfigurace nepotřebujeme, můžeme ho uvést v naší konfiguraci a právě to bude aplikováno při generování. To znamená, že pokud z nějakého důvodu potřebujeme unikátní jméno pro službu order, jednoduše necháme parametr spring.application.name.

Předpokládejme, že do služby je třeba přidat přizpůsobená nastavení pro logování, která jsou uložena v samostatném souboru, například, logback.xml. Vytvoříme pro něj samostatnou skupinu nastavení:

Snadná správa konfigurací mikroservisů pomocí microconfig.io

V základní konfiguraci uvedeme frameworku, kam umístit požadovaný soubor nastavení pro logování pomocí placeholderu @ConfigDir:

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

V souboru logback.xml nastavujeme standardní appendery, které mohou také obsahovat placeholdery, které framework změní během generování konfigurací, například:

logs/${this@name}.log

Přidáním do konfigurace služeb import logback, automaticky získáme nakonfigurované logování pro každou službu:

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

Nastal čas podrobněji se seznámit se všemi dostupnými placeholdery frameworku:

${this@env} — vrací název aktuálního prostředí.
${…@name} — vrací název komponenty.
${…@configDir} — vrací úplnou cestu k adresáři config komponenty.
${…@resultDir} — vrací plnou cestu k cílovému adresáři komponenty (získané soubory budou umístěny do tohoto adresáře).
${this@configRoot} — vrací plnou cestu k kořenovému adresáři úložiště konfigurací.

Systém také umožňuje získat proměnné prostředí, například cestu k java:
${env@JAVA_HOME}
Nebo, jelikož je rámec napsán v JAVA, můžeme získat systémové proměnné podobné volání System::getProperty pomocí konstrukce takového druhu:
${system@os.name}
Je dobré zmínit podporu jazyka pro rozšíření Spring EL. V konfiguraci platí podobné výrazy:

connection.timeoutInMs: #{5 * 60 * 1000}
datasource.maximum-pool-size: #{${this@datasource.minimum-pool-size} + 10} 

a lze použít lokální proměnné v konfiguračních souborech pomocí výrazu. #var:

#var feedRoot: ${system@user.home}/feed
folder:
 root: ${this@feedRoot}
 success: ${this@feedRoot}/archive
 error: ${this@feedRoot}/error

Takže rámec představuje poměrně mocný nástroj pro jemné a flexibilní nastavení konfigurací mikroslužeb. Rámec skvěle plní svůj hlavní úkol — odstranění kopírování a vkládání v nastaveních, konsolidaci nastavení a tím minimizaci možných chyb, zatímco umožňuje snadno kombinovat konfigurace a měnit je pro různé prostředí.

Pokud vás tento rámec zaujal, doporučuji navštívit jeho oficiální stránku a seznámit se s kompletní dokumentací, nebo prozkoumat zdrojové kódy. tady.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster