Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

Eine der Hauptprobleme bei der Entwicklung und anschließenden Wartung von Microservices ist die sorgfältige und akkurate Konfiguration ihrer Instanzen. Hierbei kann, meiner Meinung nach, ein neues Framework hilfreich sein, microconfig.io. Es ermöglicht, einige Routineaufgaben der Anwendungs настройка ziemlich elegant zu lösen.

Wenn Sie viele Microservices haben und jeder von ihnen mit seiner eigenen Konfigurationsdatei/en geliefert wird, ist die Wahrscheinlichkeit hoch, einen Fehler in einer von ihnen zu machen, den man ohne entsprechende Erfahrung und ein Logging-System nur schwer identifizieren kann. Die Hauptaufgabe, die das Framework verfolgt, besteht darin, die doppelten KonfigurationParameter der Instanzen zu minimieren und damit die Wahrscheinlichkeit von Fehlern zu verringern.

Betrachten wir ein Beispiel. Angenommen, Sie haben eine einfache Anwendung mit einer Konfigurationsdatei yaml. Das kann ein beliebiger Microservice in jeder Programmiersprache sein. Schauen wir uns an, wie man das Framework auf diesen Dienst anwenden kann.

Aber bevor wir beginnen, erstellen wir ein leeres Projekt in Idea IDE und installieren zuerst das Plugin microconfig.io:

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

Wir konfigurieren die Plugin-Startkonfiguration; Sie können die Standardkonfiguration verwenden, wie auf dem oberen Screenshot.

Unser Dienst heißt order, also erstellen wir in dem neuen Projekt eine ähnliche Struktur:

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

In den Ordner mit dem Namen des Dienstes legen wir die Konfigurationsdatei — application.yaml. Alle Microservices laufen in irgendeiner Umgebung, also müssen wir neben der Erstellung der Dienstkonfiguration auch die Umgebung selbst beschreiben: Dafür erstellen wir einen Ordner envs und fügen eine Datei mit dem Namen unserer Arbeitsumgebung hinzu. Somit wird das Framework Konfigurationsdateien für die Dienste in der Umgebung erstellen, dev, weil genau dieser Parameter in den Plugin-Einstellungen festgelegt ist.

Dateistruktur dev.yaml wird ziemlich einfach sein:

mainorder:
    components:
         - order

Das Framework arbeitet mit Konfigurationen, die in Gruppen zusammengefasst sind. Für unseren Dienst wählen wir einen Gruppennamen mainorder. Das Framework findet jede solche Gruppe von Anwendungen in der Umgebungsdatei und erstellt für alle von ihnen die Konfigurationen, die in den entsprechenden Ordnern gefunden werden.

In der Konfigurationsdatei des Dienstes order geben wir zunächst nur einen Parameter an:

spring.application.name: order

Jetzt starten wir das Plugin, und es wird die benötigte Konfiguration unseres Dienstes basierend auf dem im Eigenschaften angegebenen Pfad generieren:

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

Man kann auch ohne Installation des Plugins auskommen, indem man das Distributionspaket des Frameworks herunterlädt und es von der Kommandozeile aus ausführt. Diese Lösung eignet sich für den Einsatz auf dem Build-Server.
Es ist erwähnenswert, dass das Framework die

property -Syntax hervorragend versteht, also die üblichen Property-Dateien, die man zusammen mit den Konfigurationen verwenden kann. yaml Fügen wir noch einen Dienst hinzu

payment und erschweren wir gleichzeitig den bestehenden. 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
Im order:

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

Im und erschweren wir gleichzeitig den bestehenden.:

Das Hauptproblem dieser Konfigurationen ist das Vorhandensein von viel Copy-Paste in den Diensteinstellungen. Schauen wir uns an, wie das Framework hilft, dies zu vermeiden. Beginnen wir mit dem offensichtlichsten — der Präsenz der Konfiguration

eureka in der Beschreibung jedes Mikrodienstes. Erstellen wir ein neues Verzeichnis mit einer Einstellungsdatei und fügen wir dort die neue Konfiguration hinzu: Und in jedes unserer Projekte fügen wir jetzt die Zeile hinzu

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

Das Framework wird automatisch die eureka-Konfiguration finden und in die Konfigurationsdateien der Dienste kopieren, wobei die separate eureka-Konfiguration nicht erstellt wird, da wir sie nicht in der Umgebungsdatei angeben #include eureka.

. Der Dienst dev.yamlAußerdem können wir die Datenbankkonfiguration in eine separate Konfiguration auslagern, indem wir die Importzeile auf order:

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

Es ist erwähnenswert, dass das Framework bei jeder Änderung während der Neuerstellung der Konfigurationsdateien diese verfolgt und in eine spezielle Datei neben der Hauptkonfigurationsdatei speichert. Der Logeintrag sieht so aus: „1 Property-Änderungen gespeichert in #include eureka, oracle.

order/diff-application.yaml “. Dies ermöglicht es, Änderungen in großen Konfigurationsdateien schnell zu erkennen.Die Auslagerung gemeinsamer Teile der Konfiguration hilft, viel unnötigen Copy-Paste zu vermeiden, erlaubt jedoch nicht, flexibel Konfigurationen für verschiedene Umgebungen zu erstellen — die Endpunkte unserer Dienste sind fest und hart kodiert, das ist schlecht. Lassen Sie uns versuchen, das zu beseitigen.

Eine gute Lösung wäre es, alle Endpunkte in einer einzigen Konfiguration zu halten, auf die die anderen verweisen könnten. Zu diesem Zweck hat das Framework die Unterstützung von Platzhaltern integriert. So wird sich die Konfigurationsdatei ändern

Eine gute Lösung wäre, alle Endpunkte in einer einzigen Konfiguration zu halten, auf die sich die anderen beziehen könnten. Dazu wurde Unterstützung für Platzhalter in das Framework integriert. So wird sich die Konfigurationsdatei ändern. in der Beschreibung jedes Mikrodienstes. Erstellen wir ein neues Verzeichnis mit einer Einstellungsdatei und fügen wir dort die neue Konfiguration hinzu::

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

Schauen wir uns nun an, wie dieser Platzhalter funktioniert. Das System findet die Komponente mit dem Namen endpoints und sucht darin den Wert eurekaip, daraufhin wird dieser in unsere Konfiguration eingesetzt. Aber was ist mit unterschiedlichen Umgebungen? Dafür erstellen wir eine Konfigurationsdatei in endpoints folgender Art application.dev.yaml. Das Framework entscheidet selbst anhand der Dateierweiterung, zu welcher Umgebung diese Konfiguration gehört, und lädt sie:

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

Der Inhalt der dev-Datei:

eurekaip: 192.89.89.111
dbip: 192.168.0.100

Eine ähnliche Konfiguration können wir auch für die Ports unserer Dienste erstellen:

server.port: ${ports@order}.

Alle wichtigen Einstellungen befinden sich an einem Ort, wodurch die Wahrscheinlichkeit von Fehlern durch verstreute Parameter in den Konfigurationsdateien verringert wird.

Das Framework stellt zahlreiche bereits fertige Platzhalter zur Verfügung, zum Beispiel kann man den Namen des Verzeichnisses abrufen, in dem sich die Konfigurationsdatei befindet, und ihn zuweisen:

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

Dank dessen muss der Name der Anwendung nicht zusätzlich in der Konfiguration angegeben werden und kann ebenfalls in ein gemeinsames Modul ausgelagert werden, zum Beispiel in dasselbe eureka:

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

Die Konfigurationsdatei order wird auf eine Zeile verkürzt:

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

Falls eine Einstellung aus der übergeordneten Konfiguration nicht benötigt wird, können wir sie in unserer Konfiguration angeben, und genau diese wird bei der Generierung angewendet. Das heißt, wenn wir aus irgendeinem Grund einen eindeutigen Namen für den Dienst order benötigen, lassen wir einfach den Parameter spring.application.name.

Wir nehmen an, dass in den Dienst angepasste Logginstellungen hinzugefügt werden müssen, die in einer separaten Datei gespeichert sind, zum Beispiel logback.xml. Erstellen wir eine separate Gruppe von Einstellungen dafür:

Einfache Verwaltung von Mikrodienstkonfigurationen mit microconfig.io

In der Basis-Konfiguration geben wir dem Framework an, wo die benötigte Logdatei mit Hilfe des Platzhalters @ConfigDir:

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

In der Datei logback.xml Wir konfigurieren Standard-Appender, die ebenfalls Platzhalter enthalten können, die das Framework während der Generierung der Konfigurationen ändert, zum Beispiel:

logs/${this@name}.log

Indem wir in den Konfigurationen der Dienste den Import logback, erhalten wir automatisch konfiguriertes Logging für jeden Dienst:

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

Es ist an der Zeit, sich ausführlicher mit allen verfügbaren Platzhaltern des Frameworks vertraut zu machen:

${this@env} — gibt den Namen der aktuellen Umgebung zurück.
${…@name} — gibt den Namen der Komponente zurück.
${…@configDir} — gibt den vollständigen Pfad zum Konfigurationsverzeichnis der Komponente zurück.
${…@resultDir} — gibt den vollständigen Pfad zum Zielverzeichnis der Komponente zurück (die erhaltenen Dateien werden in dieses Verzeichnis gelegt).
${this@configRoot} — gibt den vollständigen Pfad zum Wurzelverzeichnis des Konfigurationsspeichers zurück.

Das System ermöglicht es auch, Umgebungsvariablen abzurufen, zum Beispiel den Pfad zu java:
${env@JAVA_HOME}
Außerdem, da das Framework in JAVAgeschrieben ist, können wir Systemvariablen analog zum Aufruf System::getProperty mit einer solchen Konstruktion abrufen:
${system@os.name}
Es ist erwähnenswert, dass die Unterstützung der Erweiterungssprache Spring ELvorhanden ist. In der Konfiguration sind ähnliche Ausdrücke anwendbar:

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

und es können lokale Variablen in Konfigurationsdateien mit Hilfe des Ausdrucks verwendet werden. #var:

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

Auf diese Weise stellt das Framework ein recht leistungsfähiges Werkzeug für die feine und flexible Anpassung von Microservice-Konfigurationen dar. Das Framework erfüllt seine Hauptaufgabe hervorragend – die Beseitigung von Copy-Paste in den Einstellungen, die Konsolidierung von Einstellungen und damit die Minimierung möglicher Fehler, während es gleichzeitig ermöglicht, Konfigurationen einfach zu kombinieren und für verschiedene Umgebungen zu ändern.

Wenn Sie an diesem Framework interessiert sind, empfehle ich Ihnen, die offizielle Seite zu besuchen und sich über die vollständigen Informationen zu informieren, Dokumentationoder in den Quellcodes zu stöbern. hier.

Quelle: habr.com

60GB SSD 8Gb DDR4