Ein bisschen Nachsicht bitte! Anwendungsstabilität mit MicroProfile Fault Tolerance

MicroProfile (https://microprofile.io/) enthält u. a. den Baustein MP Fault Tolerance, mit dem auf sehr einfache Weise die bekannten Stability Patterns in JEE/MicroProfile-Anwendungen eingebaut werden können.

Bei verteilten Anwendungen (Microservices) – aber nicht nur dort – können Fehler durch nicht erreichbare oder nicht funktionierende Anwendungsteile entstehen. Soll dann nicht wie bei einem Dominoeffekt die Gesamtanwendung betroffen sein, muss der aufrufende Teil resilient sein, d. h. durch Wiederholungen oder Ersatzaufrufe zu einem verträglichen Ergebnis kommen.

MP Fault Tolerance enthält Interzeptoren mit den im Folgenden beschriebenen Bindings, mit denen im Fehlerfall gewünschte Ausweichaktionen initiiert werden können.

Nochmals probieren

@Retry führt beim Auftauchen einer Exception zum wiederholten Aufruf der Methode:

@Retry(maxRetries = 4)
public int doSomethingWithRetry() {

Mit diversen Parametern von @Retry kann bestimmt werden, welche Exceptions die Wiederholungen auslösen sollen, wie lange oder wie oft es versucht werden soll und welche Wartezeit zwischen den Wiederholungen eingehalten werden soll.

Programmierte Ungeduld

Mit @Timeout kann eine Obergrenze für die Ausführungszeit einer Methode angegeben werden:

@Timeout(1000)
public int doSomethingWithTimeout() {

Rückstellende Sicherung

Circuit Breaker ist ein Pattern, das bei zu häufigen Fehlern (=Exceptions) „den Schalter öffnet“, d. h. die betroffene Methode für eine gewisse Zeit nicht mehr aufruft und statt dessen eine dementsprechende Exception wirft. Nach Ablauf der Wartezeit wird der Schalter probeweise wieder geschlossen.

MP Fault Tolerance bietet dazu @CircuitBreaker an:

@CircuitBreaker(failureRatio = 0.25, requestVolumeThreshold = 10)
public int doSomethingWithCircuitBreaker() {

Mit Parametern kann bestimmt werden, was „zu häufig“ sein soll und wann der Schalter nach Öffnung wieder geschlossen wird.

Ersatzhandlung

Sind Fehler (=Exceptions) für den Aufrufer nicht OK, kann mit @Fallback eine Ersatzaktion definiert werden:

@Fallback(fallbackMethod = "return42")
public int doSomethingWithFallback() {
  ...
}

private int return42() {
  return 42;

Plattformen

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

  • OpenLiberty (mit aktiviertem Feature mpFaultTolerance-2.0).
  • Payara.

WildFly wird MP Fault Tolerance voraussichtlich ab der Version 19 unterstützen

Die genannten Annotationen befinden sich bspw. in der Maven-Dependency org.eclipse.microprofile.fault-tolerance:microprofile-fault-tolerance-api (derzeit in Version 2.0).

Demo

In https://github.com/GEDOPLAN/microprofile-demo/tree/master/microprofile-fault-tolerance finden Sie ein Beispielprojekt mit einem Service, der die oben gezeigten Annotationen enthält und über Rest Endpoints aufgerufen 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.

Bis bald – vielleicht auch in einem unserer Trainings in Berlin, Frankfurt, Bielefeld, Köln oder bei Ihnen!

Schauen Sie sich doch mal unseren neuen Kurs zum Thema an: JEE und MicroProfile mit Quarkus

Immer noch gesund? Änderungen von MicroProfile Health 2.0 vs. 1.0

In meinem Post https://javaeeblog.wordpress.com/2019/01/27/alles-gesund-health-checking-mit-microprofile-health habe ich einen Überblick über MicroProfile Health in der Version 1.0 gegeben. Mittlerweile ist die Version 2.0 erschienen (als Teil von MicroProfile 3.0), woduch einige – teilweise inkompatible – Änderungen einhergehen:

  • Die Prüfungen werden nun in Tests der Verfügbarkeit (Liveness) und Bereitschaft (Readiness) unterteilt, um so besser die Anforderungen von Container-Infrastrukturen zu unterstützen (vgl. entsprechende Probes in Kubernetes). Statt des bisherigen Qualifiers @Health werden nun @Live bzw. @Ready zur Definition von HealthCheck-Beans verwendet:
    @ApplicationScoped
    @Liveness
    public class LivenessCheck implements HealthCheck {
    
      @Override
      public HealthCheckResponse call() {
        return HealthCheckResponse
            .named("Service1")
            .up()
            .build();
    

    @Health steht noch zur Verfügung, ist aber deprecated.

  • Die neuen Endpunkte /health/live und /health/ready veröffentlichen den Zustand von Liveness bzw Readiness:
    GET /health/live
    
    200 OK
    {
      "status": "UP",
      "checks": [{
        "name": "Service1",
        "status": "UP"
      }]
    }
    

    Der bisherige Endpunkt /health existiert weiterhin.

  • Im JSON-Format wurden die Attribute outcome und state durch status ersetzt.

Ausblenden von Default-Checks in MicroProfile Health 2.1

Die Implementierung von Healthchecks als CDI-Beans ermöglicht es, dass auch Plattform-Implementierungen/Bibliotheken Prüfergebnisse bereitstellen (bspw. ein DB Connection Pool). Setzt man die neue MicroProfile Configuration Property mp.health.disable-default-procedures auf true, werden solche Default-Checks nicht aktiviert, d. h. im Response der o. a. Endpoints befinden sich nur von der Anwendung selbst bereitgestellte Werte.

Demo

Ich habe das Beispielprojekt mit anderen MicroProfile-Demos kombiniert in https://github.com/GEDOPLAN/microprofile-demo eingecheckt. Im Verzeichnis microprofile-health finden Sie ein Demoprojekt mit zwei Health Checks, deren Ergebnis über eine Webseite beeinflusst werden kann. Die Anwendung kann als WAR-File auf einen Server mit Unterstützung von MicroProfile 3.0 deployt werden. Alternativ können über vorkonfigurierte Maven-Profile Docker-Images zum direkten Ausprobieren erstellt werden.

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