Welche Einstellung haben Sie? Anwendungskonfiguration mit MicroProfile Config

MicroProfile (https://microprofile.io/) enthält u. a. den Baustein Microprofile Config, mit dem JEE-Anwendungen aus verschiedenen Quellen heraus Konfigurationsparameter erhalten können. Neben einem API stehen auch Injektionsmöglichkeiten zur Verfügung.

Configuration API

MicroProfile Config ist durch Vorläufer-Projekte wie Apache Tamaya oder DeltaSpike Config beeinflusst und besitzt diverse Implementierungen wie SmallRye Config im WildFly. Zum portablen Zugriff auf den konkreten Provider dient die Klasse ConfigProvider und das Interface Config. Im einfachsten Fall kann ein Konfigurationswert so erfragt werden:

Config config = ConfigProvider.getConfig();
String value = config.getValue("java.version", String.class);

Config Sources

Die Konfigurationswerte werden diesen Quellen entnommen (in absteigender Priorität):

  • System Properties
  • Environment Variables
  • Classpath resource(s) META-INF/microprofile-config.properties

Nach Wunsch können die Prioritäten angepasst und zusätzliche Konfigurationsquellen ergänzt werden.

Injektion von Konfigurationswerten

Für die bequeme Nutzung in CDI Beans steht der Qualifier @ConfigProperty zur Verfügung:

@Inject
@ConfigProperty(name = "answer")
int answer;

Sollte eine solche Property-Referenz nicht befriedigt werden, d. h. sollte es im konkreten Beispiel keinen konfigurierten Wert mit dem Namen answer geben, schlägt das Deployment der Anwendung fehl. Ist das nicht erwünscht, kann als Injektionsziel ein Optional genutzt werden:

@Inject
@ConfigProperty(name = "HOME")
Optional home;

Plattformen

MicroProfile Config wird u. a. von folgenden JEE-Servern unterstützt:

  • OpenLiberty (mit aktiviertem Feature mpConfig-1.3).
  • Payara.
  • WildFly.

Die genannten Klassen befinden sich bspw. in der Maven-Dependency org.eclipse.microprofile.config:microprofile-config-api (derzeit in Version 1.3).

Demo

In https://github.com/GEDOPLAN/microprofile-demo/tree/master/microprofile-config finden Sie ein Beispielprojekt mit einem REST-Service, der API-Nutzung und Injektionsmöglichkeiten zeigt. Die Anwendung kann als WAR-File auf einen der genannten Server deployt werden. Alternativ können über vorkonfigurierte Maven-Profile Docker-Images zum direkten Ausprobieren erstellt werden.

Bis bald – vielleicht auch in einem unserer Trainings in Berlin, Bielefeld, Köln oder bei Ihnen!
https://gedoplan-it-training.de/

Werbeanzeigen

Wie läuft’s denn so? Monitoring mit MicroProfile Metrics

In meinem Blog-Eintrag „Alles gesund? Health checking mit MicroProfile Health“ habe ich dargestellt, wie einfach man den Gesundheitszustand einer Anwendung auf Basis von MicroProfile Health veröffentlichen kann. Und wenn man nun nicht nur wissen möchte, ob ein Service läuft, sondern mehr Details über den Service-Zustand erfahren möchte? Dann unterstützt uns ein weiterer Baustein: MicroProfile Metrics.

Telemetriedaten out of the box

Über den Rest-Endpoint /metrics/base werden ohne weiteren Programmieraufwand Basis-Telemetriedaten zur Verfügung gestellt:

{
  "memory.maxHeap": 8342470656,
  "memory.usedHeap": 259349504,
  "gc.G1 Young Generation.count": 28,
  "cpu.systemLoadAverage": 0.6,
  "thread.count": 111,
  ...
}

Die Daten werden in JSON geliefert, wenn man sie mit diesem Media Type anfordert (z. B. curl -H "Accept: application/json" localhost:8080/metrics/base). Mit dem Default-Media-Type text/plain werden die Daten passend für die Verarbeitung in Prometheus geliefert.

Der Endpoint /metrics/vendor ist für herstellerspezifische Messdaten aus der genutzten Plattform vorgesehen.

Anwendungsspezifische Metriken

EE-Anwendungen können weitere Messdaten bereitstellen. So kann man bspw. Methoden von CDI Beans mit der Annotation @Gauge versehen:

  @Gauge(name = "answerToLifeUniverseAndEverything", absolute = true, unit = MetricUnits.NONE)
  public long getAnswerToLifeUniverseAndEverything() {
    return 42;
  }

Die derart zur Verfügung gestellten Werte werden im Endpoint /metrics/application veröffentlicht:

{
  "answerToLifeUniverseAndEverything": 42
}

Neben dieser Möglichkeit, eigene Messwerte zu berechnen und zu veröffentlichen, kann man auch Telemetriedaten durch das Framework aggregieren lassen:

  @GET
  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
  @Timed(name = "personList", absolute = true)
  public List getAll() {
    return this.personRepository.findAll();
  }

@Timed bewirkt hier, dass die Ausführungszeiten der annotierten Methode gemessen und zu verschiedenen statistischen Werten aggregiert werden:

{
  "personList": {
    "p50": 4922800.0,
    "p75": 5160200.0,
    "p95": 1.00322E7,
    "p98": 1.00322E7,
    "p99": 1.00322E7,
    "p999": 1.00322E7,
    "min": 3218000.0,
    "mean": 5476794.800597489,
    "max": 1.00322E7,
    "stddev": 2340795.005960796,
    "count": 5,
    "meanRate": 0.6766077577220262,
    "oneMinRate": 1.0,
    "fiveMinRate": 1.0,
    "fifteenMinRate": 1.0
  }
}

Analog könnte mit @Counted ein Aufrufzähler für eine Methode etabliert werden.

Gesamt-Metrik

Der Endpoint /metrics fasst die bislang genannten Datengruppen in ein Gesamtergebnis zusammen.

Plattformen

MicroProfile Metrics wird u. a. von folgenden JEE-Servern unterstützt:

  • OpenLiberty (mit aktivierten Features mpMetrics-1.1 und monitor-1.0).
  • Payara.
  • WildFly (Achtung: WildFly hat unterschiedliche Ports für Applikations- und Management-Zugriffe, im Default 8080 und 9990. Der o. a. REST-Endpoint /metrics steht über den Management-Port zur Verfügung).

Die genannten Klassen befinden sich bspw. in der Maven-Dependency org.eclipse.microprofile:microprofile.

Demo

In https://github.com/GEDOPLAN/metrics-demo finden Sie ein Beispielprojekt mit einem REST-Service, dessen GET– und POST-Methoden so annotiert sind, dass Zeiten bzw. Aufrufzahlen gemessen werden. Der o. a. Service, der die legendäre 42 als Ergebnis liefert, ist ebenfalls im Beispielprojekt enthalten. Die Anwendung kann als WAR-File auf einen der genannten Server deployt werden. Alternativ können über vorkonfigurierte Maven-Profile Docker-Images zum direkten Ausprobieren erstellt werden.

Bis bald – vielleicht auch in einem unserer Trainings in Berlin, Bielefeld, Köln oder bei Ihnen!
https://gedoplan-it-training.de/

Alles gesund? Health checking mit MicroProfile Health

Im Bereich von Microservices und verteilten Systemen – aber nicht nur dort – ist es wichtig zu wissen, ob ein Service/System ordnungsgemäß läuft oder gestört ist. Im MicroProfile (https://microprofile.io) ist mit MicroProfile Health ein Teil enthalten, der es in Kombination mit CDI sehr einfach macht, Health Checking in EE-Anwendungen zu integrieren.

Health Check Callbacks

Die Idee von MicroProfile Health ist, dass Anwendungen auf EE-Servern oder auf Basis von MicroProfile-Frameworks ein oder mehrere Methoden zum Prüfen des Gesundheitszustandes enthalten. Der Server sammelt die Zustände bei Bedarf ein und aggregiert daraus einen Gesamtzustand, der auf dem Rest-Endpoint /health veröffentlicht wird:

GET /health

200 OK
{
  "outcome": "UP",
  "checks": [{
    "name": "Service1",
    "state": "UP",
    "data": {
      "memory": 180672240
    }
  }, {
    "name": "Service2",
    "state": "UP"
  }]
}

Die Callback-Methoden heißen – etwas uninspiriert – call und stammen aus dem Interface org.eclipse.microprofile.health.HealthCheck. Der Server sucht sich automatisch alle Klassen zusammen, die dieses Interface implementieren und mit dem CDI-Qualifier org.eclipse.microprofile.health.Health versehen sind:

@ApplicationScoped
@Health
public class HealthCheck1 implements HealthCheck {

  @Override
  public HealthCheckResponse call() {
    ...

Das Prüfergebnis können die Methoden bequem mittels Builder-Pattern zusammensetzen:

  public HealthCheckResponse call() {
    return HealthCheckResponse
        .named("Service1")
        .up()
        .withData("memory", Runtime.getRuntime().freeMemory())
        .build();

Neben up gibt es auch down sowie die Methode status, der der Gesundheitszustand als Parameter übergeben wird.

Gesamtgesundheit

Bei einem GET-Request auf den Pfad /health werden alle verfügbaren call-Methoden aus allen Anwendungen des Servers aufgerufen und zu einem Gesamtzustand kombiniert. Liefern alle Checks UP, ist das Attribut outcome im Gesamtergebnis ebenfalls UP und der Response hat den Status 200 OK. Andernfalls wird der Response mit 503 Service unavailable ausgeliefert und outcome ist darin DOWN.

Plattformen

MicroProfile Health wird u. a. von folgenden JEE-Servern unterstützt:

  • OpenLiberty (mit aktiviertem Feature mpHealth-1.0).
  • Payara.
  • WildFly (Achtung: WildFly hat unterschiedliche Ports für Applikations- und Management-Zugriffe, im Default 8080 und 9990. Der o. a. REST-Endpoint /health steht über den Management-Port zur Verfügung).

Die genannten Klassen befinden sich bspw. in der Maven-Dependency org.eclipse.microprofile:microprofile.

Demo

In https://github.com/GEDOPLAN/health-demo finden Sie ein Beispielprojekt mit zwei Health Checks, deren Ergebnis über eine Webseite beeinflusst werden kann. Die Anwendung kann als WAR-File auf einen der genannten Server deployt werden. Alternativ können über vorkonfigurierte Maven-Profile Docker-Images zum direkten Ausprobieren erstellt werden.

Ausblick

Im Beispiel wird als Zusatzinformation die Menge freien Speichers hinzugefügt, was im Kontext von Health Checking nicht grundsätzlich falsch ist, aber doch eher eine Metrik darstellt. Für deren Veröffentlichung hält MicroProfile eine weitere Teilspezifikation bereit: MicroProfile Metrics. Sie wird Gegenstand eines der nächsten Blog Posts sein – stay tuned!

Bis bald – vielleicht auch in einem unserer Trainings in Berlin, Bielefeld, Köln oder bei Ihnen!
https://gedoplan-it-training.de/