From a548534609f38596debc5a651245326d0403986b Mon Sep 17 00:00:00 2001 From: Ralf Ueberfuhr Date: Thu, 20 Jun 2024 20:16:08 +0200 Subject: [PATCH 1/2] Add liveness and readyness --- customer-api-provider/pom.xml | 4 ++ .../infrastructure/LongRunningStartup.java | 70 +++++++++++++++++++ .../src/main/resources/application.properties | 11 +++ 3 files changed, 85 insertions(+) create mode 100644 customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java diff --git a/customer-api-provider/pom.xml b/customer-api-provider/pom.xml index 5946dde..0cb2938 100644 --- a/customer-api-provider/pom.xml +++ b/customer-api-provider/pom.xml @@ -92,6 +92,10 @@ io.quarkus quarkus-jdbc-h2 + + io.quarkus + quarkus-smallrye-health + diff --git a/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java new file mode 100644 index 0000000..973e964 --- /dev/null +++ b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java @@ -0,0 +1,70 @@ +package de.schulung.sample.quarkus.infrastructure; + +import io.quarkus.runtime.Startup; +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.infrastructure.Infrastructure; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.Liveness; +import org.eclipse.microprofile.health.Readiness; + +@ApplicationScoped +public class LongRunningStartup { + + private volatile boolean initialized = false; + private volatile boolean initializingFailed = false; + + // check during startup: http://localhost:9090/q/health/ready + + private Uni doLongRunningInitialization() { + try { + Thread.sleep(5000); + initialized = true; + return Uni.createFrom().voidItem(); + } catch (InterruptedException e) { + initializingFailed = true; + return Uni.createFrom().failure(e); + } + } + + @Startup + public void init() { + Uni + .createFrom() + .voidItem() + .emitOn(Infrastructure.getDefaultWorkerPool()) + .subscribe() + .with(v -> this.doLongRunningInitialization()); + } + + @Produces + @ApplicationScoped + @Liveness + public HealthCheck myStartupLiveness() { + return new HealthCheck() { + @Override + public HealthCheckResponse call() { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initializingFailed ? result.down() : result.up()).build(); + } + }; + } + + @Produces + @ApplicationScoped + @Readiness + public HealthCheck myStartupReadyness() { + return new HealthCheck() { + @Override + public HealthCheckResponse call() { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initialized ? result.up() : result.down()).build(); + } + }; + } + +} diff --git a/customer-api-provider/src/main/resources/application.properties b/customer-api-provider/src/main/resources/application.properties index b200a40..714055f 100644 --- a/customer-api-provider/src/main/resources/application.properties +++ b/customer-api-provider/src/main/resources/application.properties @@ -19,4 +19,15 @@ persistence.sink.implementation=panache %dev.quarkus.hibernate-orm.database.generation=update +# Observability - serve on another port +# https://quarkus.io/guides/management-interface-reference +# https://quarkus.io/guides/smallrye-health +# https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +# https://developers.redhat.com/blog/2020/11/10/you-probably-need-liveness-and-readiness-probes +quarkus.management.enabled=true +quarkus.management.port=9090 +%dev.quarkus.management.host=localhost +quarkus.datasource.health.enabled=true +# Liveness: if fails -> container must be restarted +# Readyness: if fails -> container is just initializing \ No newline at end of file From d2d3daa53e89c155b3681873f0e5c4f60e18f0c3 Mon Sep 17 00:00:00 2001 From: Ralf Ueberfuhr Date: Fri, 21 Jun 2024 13:53:21 +0200 Subject: [PATCH 2/2] Use Lambdas --- .../infrastructure/LongRunningStartup.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java index 973e964..85ebad7 100644 --- a/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java +++ b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java @@ -43,13 +43,10 @@ public void init() { @ApplicationScoped @Liveness public HealthCheck myStartupLiveness() { - return new HealthCheck() { - @Override - public HealthCheckResponse call() { - final var result = HealthCheckResponse - .named("My long-running startup"); - return (initializingFailed ? result.down() : result.up()).build(); - } + return () -> { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initializingFailed ? result.down() : result.up()).build(); }; } @@ -57,13 +54,10 @@ public HealthCheckResponse call() { @ApplicationScoped @Readiness public HealthCheck myStartupReadyness() { - return new HealthCheck() { - @Override - public HealthCheckResponse call() { - final var result = HealthCheckResponse - .named("My long-running startup"); - return (initialized ? result.up() : result.down()).build(); - } + return () -> { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initialized ? result.up() : result.down()).build(); }; }