Nutzungsvorgaben Überwachung

IFS-Logo Diese Seite ist ein Teil der IsyFact-Standards. Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.

Creative Commons Namensnennung Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.

1. Einleitung

Dieses Dokument enthält die Nutzungsvorgaben zur Überwachung von Anwendungen gemäß den IsyFact Standards.

2. Aufbau und Zweck des Dokuments

In diesem Dokument werden konkrete Nutzungs- und Implementierungsvorgaben beschrieben.

Die Realisierung einer einheitlichen Überwachungsschnittstelle erlaubt es dem Betrieb frühzeitig Probleme in der Anwendungslandschaft zu erkennen und darauf zu reagieren. Dadurch können Ausfallzeiten minimiert werden.

Alle Vorgaben orientieren sich an den in den jeweiligen Kapiteln aufgeführten Anforderungen und gelten für alle Anwendungen nach IsyFact-Architektur.

3. Überwachung von Anwendungen

In diesem Kapitel werden die Anforderungen an die Überwachung von Anwendungen beschrieben. Für die Überwachung wird der Actuator von Spring Boot eingesetzt. Actuator bringt eine Reihe von eingebauten Endpoints mit und bietet auch die Möglichkeit, eigene Endpoints hinzuzufügen. So werden für Informationen über den Systemzustand die eingebauten Endpunkte health, liveness,readiness angeboten. Über den Endpoint metrics können Metriken gelesen werden. Die bereitgestellten Metriken werden von Micrometer erfasst. Eine nähere Beschreibung des Konzeptes findet sich im Dokument Überwachung - Konzept.

Der Fokus liegt dabei auf der Schaffung von einheitlichen Administrationsschnittstellen, welche dem Betrieb eine einfache Überwachung der Anwendungen erlauben. Alle Vorgaben sind beim Entwurf und der Realisierung von neuen Anwendungen nach IsyFact-Architektur zu berücksichtigen. Gegebenenfalls können in Systementwürfen Verfeinerungen der hier getroffenen Vorgaben gemacht werden. Weiterhin können die hier gemachten Vorgaben als Basis für die Beschreibung der Überwachungsschnittstelle im Betriebshandbuch der Anwendungssysteme verwendet werden.

3.1. Designvorgaben für die Überwachungsschnittstelle

Dieses Kapitel beschreibt die zu verwendenden Designmuster und Konventionen für die Überwachung mit Actuator und Micrometer.

Für die Überwachbarkeit der Anwendungen werden die folgenden Festlegungen getroffen:

  • Für die Überwachung wird Spring Boot Actuator eingesetzt.

  • Die Endpoints von Actuator werden über HTTP bereitgestellt.

  • Es werden nur die unbedingt benötigten Endpoints freigeschaltet. Alle nicht benötigten Endpoints sind zu deaktivieren.

  • Endpoints werden nur passiv benutzt. Die Anwendung wird nicht darüber konfiguriert.

  • Der Zugriff auf Endpoints wird mit Benutzername und Passwort abgesichert.

  • Anwendungen stellen einen definierten Satz von Überwachungsinformationen bereit.

Beispielhaft wird eine mögliche Konfiguration zur Anbindung beschrieben.

3.1.1. Vorgaben für bereitgestellte Informationen

In diesem Kapitel werden die Informationen beschrieben, welche jede Anwendung zur Überwachung bereitstellen muss.

Für das Anbieten dieser genormten Management-Schnittstellen wird eine Bibliothek isy-ueberwachung bereitgestellt, welche die dafür notwendigen Klassen enthält. Die Bibliothek wird in die zu überwachende Anwendung eingebunden. Durch das Einbinden von isy-ueberwachung werden auch die für Actuator und Micrometer benötigten Dritt-Bibliotheken eingebunden.

3.1.1.1. Allgemeine Überwachungsinformationen

Actuator stellt über den metrics Endpoint allgemeine Überwachungsinformationen bereit. Die folgenden Metriken müssen durch Spring Boot automatisch registriert und bereitgestellt werden:

  • JVM Metriken

    • Speicher und Puffer

    • Statistiken zur Garbage Collection

    • Nutzung von Threads

    • Anzahl der geladenen Klassen

  • Metriken zur Prozessorauslastung

  • Metriken für Dateideskriptoren

  • Metriken zur Uptime der Anwendung

  • Tomcat-Metriken

3.1.1.2. Informationen von Services

Tabelle 1 zeigt eine Liste der zu überwachenden bzw. anzubietenden Informationen für die Services von Anwendungen. Die dort aufgelisteten Informationen müssen für jeden Service einzeln angeboten werden.

Tabelle 1. Standard Überwachungsinformationen für Services
Tags: anwendung = <Package der Anwendung>, servicestatistik = <Name des Service>

AnzahlAufrufeLetzteMinute

Liefert die Anzahl der in der letzten Minute erfolgten Aufrufe des Services insgesamt.

AnzahlFehlerLetzteMinute

Liefert die Anzahl der in der letzten Minute erfolgten Aufrufe des Services, bei denen ein technischer Fehler aufgetreten ist.

DurchschnittsDauerLetzteAufrufe

Liefert die durchschnittliche Bearbeitungsdauer der letzten 10 Aufrufe der Services in Millisekunden (einfacher gleitender Durchschnitt).

ServiceStatistic

Stellt Informationen über den Dienstnamen und die Version bereit.

Die Summe der Aufrufe wird alle 60 Sekunden aktualisiert.

Das Interface ServiceStatistik ermöglicht es, Klassen zum Sammeln von Metriken zu erstellen. Alle ServiceStatistik implementierenden Beans werden automatisch der Micrometer-Registry hinzugefügt.

Da die gesammelten Informationen für alle Services identisch sind, bringt isy-ueberwachung eine Klasse DefaultServiceStatistik mit, die diese transparent erfasst.

Um die Informationen für mehrere Services in einer Anwendung anzubieten, wird die Klasse mehrfach als Spring-Bean konfiguriert. Die Aktualisierung der Daten in DefaultServiceStatistik wird in der Service-Fassade der jeweiligen Komponente durchgeführt. Dazu wird per Spring ein AOP-Advice für die Service-Methoden der Komponente definiert. Die Konfiguration für eine DefaultServiceStatistik-Bean und den dazugehörigen AOP-Advice ist beispielhaft in Listing 1 dargestellt.

Listing 1. ServiceStatistik-Bean und AOP-Advice für die Service-Methoden der Komponente
@Configuration
@EnableAspectJAutoProxy
public class UeberwachungConfig {

    @Bean
    public DefaultServiceStatistik verwaltungMonitor() {
        return new DefaultServiceStatistik("servicestatistik", "verwaltung");
    }

    @Bean
    public Advisor verwaltungMonitorAdvice() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("target(de.bund.bva.anwendung.service.verwaltung.VerwaltungRemoteBean)");
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, verwaltungMonitor());
        advisor.setOrder(1000);
        return advisor;
    }
}

Der Advice bewirkt, dass jeder Aufruf von VerwaltungRemoteBean zu einem Aufruf der Methode zaehleAufruf in der Bean verwaltungMonitor führt. Die Bean verwaltungMonitor ist die DefaultServiceStatistik-Instanz für die VerwaltungRemoteBean. Eine entsprechende Konfiguration wird also für jeden Service in die Spring-Konfiguration aufgenommen.

Für das Monitoring per AOP werden intern Datenstrukturen gespeichert, die vorhalten, an welchen Stellen Aspekte eingebracht werden. Das kann, wenn eine große Anzahl von Service-Klassen mit vielen Methoden genutzt wird, zu einem großen Speicherverbrauch führen. Dies muss beim Design der Services berücksichtigt werden. Da in Anwendungen pro Komponente in der Regel ein Service angeboten wird und in Anwendung gemäß Referenzarchitektur nur eine eher kleine Anzahl von Komponenten vorhanden ist, stellt dies in der Regel kein Problem dar.

3.1.1.3. Überwachung von Caches

Für Caches, die beim Start der Anwendung initialisiert sind, werden automatisch im Endpoint metrics Statistiken mit dem Präfix cache. geführt. Die Art der angezeigten Statistiken ist von der verwendeten Cache-Implementierung abhängig.

3.1.2. Implementierung von eigenen Metriken

Zusätzlich zu den eingebauten Metriken kann eine Anwendung selber Metriken aufzeichnen und über Micrometer registrieren.

3.1.2.1. Implementierung

Zum Einsatz von eigenen Metriken werden die von Micrometer angebotenen abstrakten Meter über eine MeterRegistry registriert und dann in der Anwendung mit Daten befüllt.

Die MeterRegistriy wird von Spring per Dependency Injection bereitgestellt. Bei der Registrierung eines Meters ist ein Tag zur Unterscheidung und eine Beschreibung zu setzen. Ein Beispiel zur Registrierung und Verwendung eines Meters am Beispiel eines Counters zeigt Listing 2. Dort wird ein Counter mit dem Namen eintrag.neu mit einem Tag registriert, der aus einem Schlüssel komponente mit dem Wert verwaltung besteht. Zu den Namenskonventionen bei der Vergabe von Namen und Tags siehe Namenskonventionen.

Listing 2. Registrierung und Verwendung eines Counters.
@Component
public class VerwaltungImpl implements Verwaltung {

    private final Counter neuerEintragCounter;

    ...

    public VerwaltungImpl(MeterRegistry registry) {
        neuerEintragCounter = registry.counter("eintrag.neu", "komponente", "verwaltung");
        ...
    }

    public EintragDaten neuerEintrag(...) {
        ...
        neuerEintragCounter.increment();
        ...
    }
}
3.1.2.2. Namenskonventionen

Bei der Benennung von Metern und Tags sind Konventionen einzuhalten.

3.1.2.2.1. Benennung von Metern

Die Konventionen von Micrometer bei der Vergabe von Namen sehen die Verwendung von kleingeschriebenen Wörtern vor, die durch Punkte (.) getrennt werden.

registry.timer("http.server.requests");

Verschiedene Monitoring-Systeme haben ihre eigenen Namenskonventionen, die untereinander inkompatibel sein können. Deshalb sorgt jede Implementierung von Micrometer zur Anbindung eines Monitoring-Systems dafür, dass die Standardkonvention in die Namenskonvention des jeweiligen Monitoring-Systems übertragen werden kann. Gleichzeitig stellt die Einhaltung der Konvention sicher, dass keine im angebundenen Monitoring-Systems verbotenen Zeichen verwendet werden und die Namen der Metriken somit möglichst portabel sind.

3.1.2.2.2. Benennung von Tags

Die Benennung von Tags folgt syntaktisch dem gleichen Schema wie die Benennung von Metern. Damit wird auch hier eine Übersetzung der Namen in die Konventionen des Monitoring-Systems möglich. Bei der Auswahl der Bezeichner ist darauf zu achten, dass diese sprechend sind. Das folgende Beispiel zeigt die Verwendung von Tags. Es sollen die Zahl der HTTP Requests und die Zahl der Datenbankzugriffe gemessen werden.

registry.counter("database.calls", "db", "users")
registry.counter("http.requests", "uri", "/api/users")

Damit kann man über den Namen 'database.calls' die Zahl aller Zugriffe auf die Datenbank abfragen und dann über den Tag die Aufrufe nach Datenbank weiter aufschlüsseln.

3.1.2.2.3. Allgemeine Tags

Allgemeine Tags werden zu jeder Metrik hinzugefügt, die im System registriert wird. Diese werden zur Kennzeichnung der betrieblichen Systemumgebung (Anwendung, Host, Instanz, etc.) gesetzt. Allgemeine Tags können über Properties in application.properties gesetzt werden. Die Properties sind dabei nach dem Schema

management.metrics.tags.<Schlüssel>=<Wert>

aufgebaut. Damit jeder Metrik ein Tag hinzugefügt wird, der den Namen der Anwendung enthält, wird die Property

management.metrics.tags.anwendung=beispielanwendung

gesetzt.

3.1.2.3. Performance

Die im Konzept beschriebenen Überwachungsfunktionen dürfen keinen relevanten negativen Einfluss auf die Performance der Anwendung haben. Dazu sind neben der Einhaltung der in dem Dokument Überwachung - Konzept beschriebenen Vorgaben noch einige grundlegende Regeln zu beachten:

  • Da nicht auszuschließen ist, dass ein Überwachungswerkzeug sehr häufig Informationen aus den Endpoints abruft, darf das Bereitstellen der Informationen keine zeitaufwändigen Aktionen im Anwendungssystem veranlassen.

  • Bei der Bereitstellung weiterer Überwachungsinformationen ist darauf zu achten, dass die Ermittlung der Kennzahlen keinen relevanten negativen Einfluss auf die Performance der Anwendung hat. Insbesondere dürfen keine fachlichen Funktionen des Anwendungskerns aufgerufen werden.

3.1.3. Statische Informationen über die Anwendung

Der Info-Endpoint liefert statische Informationen über die Anwendung und ist im Baustein Überwachung aktiviert. Die Informationen müssen von der Anwendung explizit bereitgestellt werden. Es können z. B. Informationen über den Build und Quellcode-Stand (Git) der Anwendung geliefert werden. Durch die Einbindung von passenden Maven-Plugins können diese Informationen automatisch bei jedem Build erzeugt werden:

Listing 3. Maven Konfiguration für Build- und GIT Informationen
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
</plugin>

Durch das Einbinden der Plugins (s. Listing 3) werden 2 Dateien mit folgenden Informationen erzeugt:

  • build-info.properties mit den Keys:

    • build.artifact

    • build.group

    • build.name

    • build.time

    • build.version

  • git.properties mit den Keys:

    • git.branch

    • git.commit.id.abbrev

    • git.commit.time

Die Werte der Keys werden über den Info-Endpoint bereitgestellt.

Bei Bedarf können weitere statische Informationen durch zusätzliche Konfiguration von der Anwendung bereitgestellt werden.

Weiterführende Informationen enthält die Dokumentation von Spring Boot zum Info-Endpoint.

3.1.4. Konfiguration und Absicherung von Endpoints

Gemäß den Vorgaben werden nicht benötigte Endpoints deaktiviert, und jeder veröffentlichte Endpoint wird durch Authentifizierung abgesichert.

3.1.4.1. Konfiguration von Endpoints

Zur Überwachung einer Anwendung werden die folgenden eingebauten Endpoints verwendet:

  • health,

  • liveness,

  • readiness,

  • metrics.

Diese sind bereits mit Standardwerten konfiguriert. Da der Endpoint health seine Informationen aus einem Cache abfragt, welcher von einem Task befüllt wird, werden die in Listing 4 gezeigten Properties in application.properties gesetzt, um das Starten der Tasks zu aktivieren.

Listing 4. Properties zur Aktivierung des Tasks
isy.task.autostart=true
isy.task.default.host=

Endpoints können einzeln aktiviert oder deaktiviert werden. Damit wird gesteuert, ob der Endpoint erstellt wird und die dafür notwendigen Beans erzeugt werden. Für den Zugriff von außerhalb muss der Endpoint zusätzlich über eine Schnittstelle (HTTP oder JMX) bereitgestellt werden.

Da von Spring standardmäßig fast alle Endpoints aktiviert sind, werden zunächst alle Endpoints ausgeschaltet, und anschließend die Endpoints health, liveness, readiness und metrics explizit wieder aktiviert. Die Bereitstellung der Endpoints erfolgt nur über HTTP.

Der Task für die Aktualisierung der Informationen für den Endpoint health muss regelmäßig ausgeführt werden. Durch das Caching ist gewährleistet, dass die wiederholte Abfrage des Endpoints nicht übermäßige Abfragen erzeugt, die auf andere Systeme propagieren können.

Für diese Konfiguration sind die in Listing 5 gezeigten Properties standardmäßig gesetzt. Diese können bei Bedarf in application.properties überschrieben werden.

Listing 5. Properties zur Konfiguration der Endpoints
management.endpoints.enabled-by-default=false
management.endpoint.health.enabled=true
management.endpoint.metrics.enabled=true
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=health, metrics, info
management.endpoints.jmx.exposure.exclude=*

isy.task.tasks.isyHealthTask.ausfuehrung=FIXED_DELAY
isy.task.tasks.isyHealthTask.initial-delay=5s
isy.task.tasks.isyHealthTask.fixed-delay=30s
3.1.4.2. Absicherung von Endpoints

Der Zugriff auf Endpoints muss mit einer Authentifizierung abgesichert werden. Eine Standardkonfiguration für Spring Security, die alle Endpunkte mit HTTP Basic Authentication absichert, wird durch die Klasse IsyActuatorSecurityAutoConfiguration bereitgestellt.

Standardmäßig wird der Zugriff auf Endpunkte durch eine HTTP Basic Authentifizierung aktiviert, wenn die Dependencies:

  • org.springframework.security:spring-security-config und

  • org.springframework.security:spring-security-web

im Klassenpfad verfügbar sind und Benutzername sowie Passwort zum Zugriff auf die Endpunkte in der application.properties konfiguriert sind (siehe Listing 6). Ohne Konfiguration von Benutzername und Passwort ist die Absicherung nicht aktiv.

Listing 6. Konfiguration der Absicherung in application.properties
# Benutzername des Monitoring Users (Default: null)
isy.ueberwachung.security.username=<username>
# Passwort des Monitoring Users (Default: null)
isy.ueberwachung.security.password=<password>

Die Standardabsicherung der Endpunkte kann per Konfiguration von der Spring AutoConfiguration ausgeschlossen und überschrieben werden, falls die Anforderungen der Anwendung von der Standardabsicherung abweichen:

spring.autoconfigure.exclude=de.bund.bva.isyfact.ueberwachung.autoconfigure.IsyActuatorSecurityAutoConfiguration

3.1.4.2.1. Abschalten der Absicherung für die Entwicklung

Um die Authentifizierung für die Endpoints bei der Entwicklung abzuschalten, kann in [listing-endpointsecurityconfig] gezeigte Konfiguration über ein Spring-Profil (im Beispiel produktion) aktiviert bzw. deaktiviert werden.

3.1.5. Prüfung der Verfügbarkeit

Anwendungen nach IsyFact-Architektur sollen Mechanismen bereitstellen, die es erlauben, die Verfügbarkeit der Anwendung durch eine betriebliche Überwachung zu prüfen.

Grundlage dafür ist die Bereitstellung eines HealthEndpoints.

3.1.5.1. Konfiguration des Nachbarsystem-HealthIndicator

Jede Anwendung stellt einen HealthEndpoint unter /actuator/health bereit. Zur Konfiguration siehe auch Konfiguration von Endpoints. Dieser zeigt den Status des Systems abhängig von allen vorhandenen Health-Indikatoren (HealthIndicator).

Der Baustein liefert einen Nachbarsystem-Indikator mit, der den HealthEndpoint aller konfigurierten Nachbarsysteme abfragt.

Dieser lässt sich wie folgt konfigurieren:

Listing 7. Konfiguration des NachbarsystemIndicators
## Konfiguration von Timeout und Retries bei der Abfrage von Nachbarsystemen
isy.ueberwachung.nachbarsystemcheck.anzahlretries=1
isy.ueberwachung.nachbarsystemcheck.timeout=2s

## Konfiguration eines Nachbarsystems, das überwacht wird
isy.ueberwachung.nachbarsysteme.beispielnachbar.systemname=Beispielnachbar
isy.ueberwachung.nachbarsysteme.beispielnachbar.healthendpoint=http(s)://example.com/actuator/health
isy.ueberwachung.nachbarsysteme.beispielnachbar.essentiell=false

# weitere Nachbarn
#isy.ueberwachung.nachbarsysteme.anderernachbar.systemname=EinAndererNachbar
#...

Unter isy.ueberwachung.nachbarsystemcheck sind die Zeit bis zum Timeout einer Anfrage und die Anzahl der Wiederholungsversuche pro Abfrage konfigurierbar. Ist nichts anderes konfiguriert, ist der Standardwert hier 3 Sekunden bis zum Timeout und ein Wiederholungsversuch. Alle abzufragenden Nachbarsysteme sind unter isy.ueberwachung.nachbarsysteme zu konfigurieren. Im Listing oben ist beispielnachbar ein selbst zu wählender Schlüssel. Für jeden Schlüssel sind folgende Properties zu setzen:

  • systemname: Wird in der Log-Ausgabe als Name des Nachbarsystems verwendet

  • healthendpoint: Die URL, unter der der HealthEndpoint des Nachbarsystems zu erreichen ist

  • essentiell (true/false) : Ist ein essenzielles Nachbarsystem nicht erreichbar, wird der Status des Nachbarsystem-Indikators auf DOWN gesetzt und ein Error geloggt. Nicht essenzielle Nachbarsysteme beeinflussen den Status nicht und werden, falls sie nicht erreichbar sind, nur als Warning geloggt.

3.1.6. Korrelations-ID bei einem Nachbarsystem-HealthIndicator

Eine Korrelations-ID muss gesetzt werden, wenn ein HealthIndicator ein Nachbarsystem aufruft. Diese wird im Logging Kontext benötigt. Konkret wird die Korrelations-ID im Task Scheduling gesetzt. isy-ueberwachung liefert nur eine Default-Konfiguration für einen HealthIndicator.

3.1.7. Implementierung weiterer eigener Health-Indikatoren

Es können weitere Indikatoren zur Überprüfung anderer Komponenten implementiert werden. Um einen eigenen HealthIndicator zu implementieren, wird eine Spring-Bean registriert, die das Interface HealthIndicator implementiert. Dort wird die Methode health() implementiert, die eine Objekt vom Typ Health zurückgibt. Diese enthält den Status der überprüften Komponente und kann optional weitere Details zur Anzeige enthalten. HealthIndicator werden automatisch von Spring Boot erkannt und im health Endpoint bereitgestellt.

Hierfür gelten folgende Richtlinien:

  • Der HealthIndicator wird als Teil der Administrationskomponente implementiert.

  • Der HealthIndicator darf keine fachlich relevanten Daten verändern.

Neben den Nachbarsystemen sind weitere Überprüfungen sinnvoll:

  • Verfügbarkeit weiterer genutzter Ressourcen, wie beispielsweise das IAM-System oder genutzte FTP-Verzeichnisse. Bei der Prüfung der genutzten Ressourcen ist zu beachten, dass sich die Implementierung nicht aufhängt und somit die Prüfung nicht weiterläuft. Um dies zu vermeiden, sollte zur Prüfung der genutzten Ressourcen das Future-Pattern wie in Listing 8 gezeigt, verwendet werden.

    Als Beispiel sei hier das IAM-System genannt. Zur Prüfung des IAM-Systems wird in der Regel eine Beispielanfrage an den Server gesendet. Ist vor das IAM-System ein Loadbalancer geschaltet, so kann es nach einem Fail-Over passieren, dass diese Beispielanfrage endlos läuft.

  • Anwendungen, die HTTP-Invoker Schnittstellen bereitstellen, müssen nach Vorgabe das Administration-Bean anbieten, um die Erreichbarkeit des Systems zu prüfen. Die Ping-Methode dieses Beans kann zur Implementierung eines Health-Indikators verwendet werden, wie in Listing 9 dargestellt.

    Bei der Erstellung des AdministrationRemoteBean muss der Request-Timeout gesetzt werden, damit Ressourcen nicht zu lange blockiert werden.
Listing 8. Demonstration Future-Pattern
boolean pruefeSystem() {
    ExecutorService executor = Executors.newCachedThreadPool();
    Future<Boolean> future = executor.submit((Callable<Boolean>) () -> {
        if (!anwendungXYZ.isAnwendungXYZAlive()) {
            throw new AnwendungXYZNotAvailableException();
        }
        return true;
    });

    try {
        return future.get(10, TimeUnit.SECONDS);
    } catch (Exception e) {
        return false;
    }
}
Listing 9. Beispiel: Implementierung eines eigenen Health-Indikators
/** Health configuration. */
@Configuration
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class)
public class HealthConfiguration {
    /** Ping message. */
    private final String pingMsg;

    /**
     * @param systemName current system name
     */
    HealthConfiguration(@Value("${system.name}") String systemName) {
        pingMsg = "Ping from " + systemName;
    }

    /**
     * App2 {@link HealthIndicator}; available in an entry named {@code app2}.
     * @param app2AdminBean App2 {@link AdministrationRemoteBean}
     */
    @Bean
    HealthIndicator app2HealthIndicator(AdministrationRemoteBean app2AdminBean) {
        return () -> {
            try {
                app2AdminBean.ping(pingMsg);
                return Health.up().build();
            } catch (Exception e) {
                return Health.down(e).build();
            }
        };
    }
}

3.1.8. Liveness und Readiness Zustände

Wie in Kapitel Informationen über den Systemzustand beschrieben sind Liveness und Readiness Zustände, die einem feingranularen Monitoring dienen.

Anwendungen nach dem IsyFact Standard sollen, neben dem Health-Zustand, Informationen über diese Zustände zur Verfügung stellen. Liveness und Readiness sind konzeptionell beschrieben und werden nicht von der isy-überwachung-Bibliothek zur Verfügung gestellt. Die tatsächlich korrekte Abbildung der Zustände hängt von den betrieblichen Gegebenheiten und der zu überwachenden Anwendung ab. Daher werden hier Vorgaben für die bedarfsgerechte Darstellung von Liveness und Readiness gemacht.

3.1.8.1. Bereitstellen von Liveness und Readiness Probes

Liveness und Readiness Probes können in der Anwendungskonfiguration aktiviert werden: (vgl. Baeldung: Liveness und Readiness Probes in Spring Boot):

Listing 10. Aktivierung von Liveness und Readiness in den application.properties
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true

Damit werden die der Anwendung zur Verfügung stehenden Informationen aus dem ApplicationContext und dem Lebenszyklus der Anwendung genutzt, um die Ausprägung des jeweiligen Zustands zu bestimmen. Verfügt die Anwendung über keine Abhängigkeiten, die die Zustände beeinflussen, ist die beschriebene Aktivierung zur Verwendung der Zustände ausreichend. Ob Abhängigkeiten mit Einfluss auf die Zustände gemäß deren Definition bestehen, ist von den Entwickelnden zu beurteilen.

3.1.8.2. Update des Liveness States

In den meisten Fällen reicht für die korrekte Abbildung des Liveness-Zustands, die vom Spring Boot Actuator standardmäßige Ermittlung des Zustands aus. Wenn der ApplicationContext erfolgreich initialisiert ist, geht Spring Boot grundsätzlich davon aus, dass die Anwendung in einem korrekten Zustand ist. Die Anwendung wird dann als alive betrachtet (vgl. Spring Boot Liveness Event). Ist der Liveness-Zustand neben dem funktionierenden ApplicationContext von der korrekten Funktion von weiteren, anwendungsspezifischen Komponenten abhängig, müssen die Komponenten im Liveness-Zustand berücksichtigt werden.

Wenn ein Szenario in der Anwendung vorliegt, das einen Neustart erforderlich macht, ist dies im Liveness-Status zu berücksichtigen.

Ein Beispiel für einen solchen Fall ist ein nicht mehr ordnungsgemäß funktionierender Cache. In einem solchen Fall sind die Vorgaben im Kapitel Konkrete Implementierung von Zustandsänderungen zu beachten.

Liveness darf nicht durch Check externer Systeme beeinflusst werden. Andernfalls könnte es sein, dass einem Fehlschlagen eines externen Systems (Datenbank, Web API, externer Cache, …​) ein Neustart des Systems folgt, welcher Fehlerkaskaden über die Anwendungslandschaft auslöst.

3.1.8.3. Update des Readiness States

In vielen Fällen sind für das korrekte Abbilden der Readiness einer Anwendung weitere Zustandsindikatoren notwendig. Die Zustandsindikatoren zeigen an, ob die Anwendung Anfragen korrekt verarbeiten kann. Diese Fähigkeit kann von anwendungsinternen Vorgängen abhängen, z.B. der Abschluss des vollständigen Ladens von notwendigen Daten, oder die Erreichbarkeit angebundener externer Systeme. Angebundene Systeme, die aus Sicht der Anwendung nutzbar zur Verfügung stehen müssen, sind im Readiness-Zustand zu berücksichtigen. Gemäß dem IsyFact Vorgaben zählen dazu alle als essenziell eingestuften Nachbarsysteme (Vgl. Überwachungskonzept-Essenzielle Nachbarsysteme.)

3.1.8.4. Konkrete Implementierung von Zustandsänderungen

Grundsätzlich besteht für jede Komponente die Möglichkeit, den Zustand der Anwendung direkt über ein AvailabilityChangeEvent zu verändern. Durch die dieses Events wird die Zustandsänderung in den Gesamtstatus der Anwendung integriert. Damit ist eine vorhandene Implementierung um eine Veränderung des jeweils relevanten Zustands erweiterbar z.B. bei der Verarbeitung von Exceptions.

Listing 11. AvailabilityChangeEvent
AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);
AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

Sind weitere Indikatoren für den Liveness- oder Readiness-Zustand relevant, sind Gruppen zu nutzen (Vgl. Spring Boot Health Groups). Dieses Vorgehen ermöglicht eine strukturierte Übersicht und erleichtert die Veränderbarkeit der Überwachung, wenn auf Anwendungsänderungen oder veränderte Betriebsbedingungen zu reagieren ist. Darüber hinaus lassen sich für die korrekte Abbildung der Readiness vorkonfiguriert Informationen angebundener Systeme nutzen. Spring Boot Actuator bietet, über vorkonfigurierte HealthIndictor-Interfaces, die Integration der health-Informationen angebundener Systeme an. Diese müssen über Spring Boot-Mechanismen angebunden sein und über zugehörige Konfigurationsdateien im Klassenpfad vorkommen. Eine Liste der vorkonfigurierten HealthIndicators und detaillierte Informationen sind hier einzusehen. Wird die Readiness des Systems von der Erreichbarkeit weiterer essenzieller Nachbarsysteme beeinflusst, sind diese als Komponenten unter der Verwendung des HealthIndicator-Interface zu implementieren. Bei einer Verwendung der Bibliothek isy-überwachung kann hierfür der NachbarsystemIndicator genutzt werden. Sind weitere Komponenten in den Zuständen zu berücksichtigen, sind die Vorgaben des Kapitels Implementierung weiterer eigener Health-Indikatoren zu beachten. In den application.properties sind alle Indikatoren (<customCheck>) in der jeweiligen Gruppe hinzuzufügen:

Listing 12. Aktivierung und Gruppierung von Liveness und Readiness in den application.properties
management.endpoint.health.group.readiness.include=readinessState, <customCheck>
management.endpoint.health.group.liveness.include=livenessState, <customCheck>

Mit dieser Konfiguration in den application.properties werden alle in der Gruppe aufgeführten Indikatoren über eine logische UND-Verknüfung in dem jeweiligen Status berücksichtigt.

3.1.8.5. Logging der Zustandsänderung

Wenn sich der Zustand ändert, ist dies im Logging zu protokollieren. Dieses Vorgehen ist gegenüber dem Protokollieren jeder Zustandsprüfung zu bevorzugen. Das Protokollvolumen wird reduziert und Probleme zu erkennen wird vereinfacht.

Listing 13. EventListener zum Loggen der Zustandsänderung
@EventListener
public void onApplicationEvent(AbstractHealthIndicator healthIndicator) {
    // Log der Veränderung des Liveness- oder Readiness-Zustands mit einer Fallunterscheidung
}

3.2. Anbindung eines Monitoring-Systems

Zur Anbindung eines konkreten Monitoring-Systems wird die passende Meter Registry für das Monitoring-System als Maven-Abhängigkeit in die pom.xml aufgenommen.

Die Namen der Abhängigkeiten folgen dem Schema micrometer-registry-<Monitoring-System>. Soll beispielweise Prometheus angebunden werden, muss die folgende Abhängigkeit eingetragen werden.

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

Häufig ist keine weitere Konfiguration notwendig, da die Anbindung durch Spring Boot automatische konfiguriert wird. Die Konfiguration für die unterstützten Monitoring-System ist in Monitoring-Systeme beschrieben.

3.3. Anwendungen deaktivierbar machen

Für die Durchführung von Updates beim Deployment ist es notwendig, einzelne Knoten eines Anwendungsclusters aus dem Loadbalancing herauszunehmen, sodass dieser Knoten keine Anfragen mehr vom Loadbalancer zugeteilt bekommt.

3.3.1. Integration des Loadbalancer-Servlets

Das Loadbalancing-Servlet ist als Teil der Bibliothek isy-ueberwachung. Es wird automatisch durch die Einbindung der Bibliothek als Servlet registriert. Standardmäßig verwendet das Servlet die Datei /WEB-INF/classes/config/isAlive als IsAlive-Datei.

Nach dem Deployment entspricht dies der Datei /etc/<anwendungsname>/isAlive.

Die zu suchende Datei kann bei Bedarf durch die Property isy.ueberwachung.loadbalancer.isAliveFileLocation in application.properties geändert werden.

3.3.2. Nutzung des Loadbalancing-Servlets

Durch die oben beschriebene Konfiguration kann die gewünschte Verfügbarkeit der Anwendung über die URL http(s)://<serverurl>/<anwendungsname>/Loadbalancer abgefragt werden.

Zur Steuerung des Loadbalancing-Servlets muss die IsAlive-Datei im Konfigurationsverzeichnis der Anwendung durch den Betrieb angelegt bzw. entfernt werden. Der Standardname für die IsAlive-Datei ist /etc/<anwendungsname>/isAlive. Dieses kann der Betrieb bei Bedarf über ein Shell-Skript automatisieren.