SmallRye Health

Prerequisites

如要完成本指南,您需要:

  • Roughly 15 minutes

  • An IDE

  • 安装了 JDK 17+,已正确配置 JAVA_HOME

  • Apache Maven ${proposed-maven-version}

  • 如果你想使用 Quarkus CLI, 则可以选择使用

  • 如果你想构建一个本机可执行文件(或如果你使用本机容器构建,则使用 Docker),则可以选择安装 Mandrel 或 GraalVM 以及 configured appropriately

Architecture

在本指南中,我们将构建一个简单的 REST 应用程序,根据规范在 `/q/health/live`和 `/q/health/ready`端点公开 MicroProfile Health 功能。

Solution

我们建议您按照下一部分中的说明逐步创建应用程序。但是,您可以直接转到已完成的示例。

克隆 Git 存储库:git clone $${quickstarts-base-url}.git,或下载一个 $${quickstarts-base-url}/archive/main.zip[存档]。

此解决方案位于 microprofile-health-quickstart$${quickstarts-base-url}/tree/main/microprofile-health-quickstart[目录] 中。

Creating the Maven Project

首先,我们需要一个新项目。使用以下命令创建一个新项目:

CLI
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
    --no-code
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 --gradle--gradle-kotlin-dsl 选项。 有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。

Maven
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId={create-app-group-id} \
    -DprojectArtifactId={create-app-artifact-id} \
    -DnoCode
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

适用于 Windows 用户:

  • 如果使用 cmd,(不要使用反斜杠 \ ,并将所有内容放在同一行上)

  • 如果使用 Powershell,将 -D 参数用双引号引起来,例如 "-DprojectArtifactId={create-app-artifact-id}"

此命令将生成一个项目,导入 `smallrye-health`扩展。

如果您已配置 Quarkus 项目,可以通过在项目根目录中运行以下命令为项目添加 `smallrye-health`扩展:

CLI
quarkus extension add {add-extension-extensions}
Maven
./mvnw quarkus:add-extension -Dextensions='{add-extension-extensions}'
Gradle
./gradlew addExtension --extensions='{add-extension-extensions}'

这会将以下内容添加到构建文件中:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-health</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-smallrye-health")

Running the health check

导入 `smallrye-health`扩展将直接公开三个 REST 端点:

  • /q/health/live- 应用程序已启动并正在运行。

  • /q/health/ready- 应用程序已准备就绪以响应请求。

  • /q/health/started- 应用程序已启动。

  • /q/health- 累积应用程序中的所有运行状况检查程序。

要检查 `smallrye-health`扩展是否按预期工作,请:

  • 使用以下命令启动 Quarkus 应用程序:include::./_includes/devtools/dev.adoc[]

  • 使用浏览器或 `curl [role="bare"]http://localhost:8080/q/health/live`访问 `http://localhost:8080/q/health/live`端点

所有 `health`REST 端点都会返回一个带有两个字段的简单 JSON 对象:

  • status- 这是所有运行状况检查程序的总体结果

  • checks- 这是一个由各个检查组成的数组

运行状况检查的 `status`通常根据逻辑 计算所有已声明的运行状况检查程序。由于我们尚未指定任何运行状况检查程序,因此 `checks`数组是空的,因此让我们定义一些。

Management interface

默认情况下,运行状况检查在 HTTP 主服务器上公开。您可以通过使用 `quarkus.management.enabled=true`属性启用管理界面在单独的网络接口和端口上公开。有关更多信息,请参阅 management interface reference

Creating your first health check

在本节中,我们将创建我们的第一个简单的运行状况检查程序。

创建 `org.acme.microprofile.health.SimpleHealthCheck`类:

package org.acme.microprofile.health;

import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Liveness;

import jakarta.enterprise.context.ApplicationScoped;

@Liveness
@ApplicationScoped 1 2
public class SimpleHealthCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.up("Simple health check");
    }
}
1 建议使用 `@ApplicationScoped`或 `@Singleton`作用域对运行状况检查类进行注释,以便将单个 Bean 实例用于所有运行状况检查请求。
2 如果使用其中一个运行状况检查注释对 Bean 类进行了注释且未声明任何作用域,那么 `@Singleton`作用域将自动使用。

正如您所见,运行状况检查程序被定义为实现 HealthCheck 接口的 CDI bean,并用运行状况检查限定符之一进行注释,例如:

  • @Liveness - 可在 /q/health/live 访问的活动检查

  • @Readiness - 可在 /q/health/ready 访问的就绪检查

HealthCheck 是一个函数接口,其单一方法 call 返回一个 HealthCheckResponse 对象,该对象可通过示例中所示的流畅构建器 API 轻松构建。

因为我们已经在 dev 模式下启动了 Quarkus 应用程序,只需通过刷新浏览器窗口或使用 curl [role="bare"]http://localhost:8080/q/health/live 重复请求 http://localhost:8080/q/health/live 即可。由于我们定义了运行状况检查为活动检查程序(使用 @Liveness 限定符),因此新的运行状况检查程序现在存在于 checks 数组中。

恭喜!您已创建第一个 Quarkus 运行状况检查程序。我们继续探索 SmallRye Health 还能做什么。

Adding a readiness health check procedure

在上一部分中,我们创建了一个简单的活动运行状况检查程序,该程序指出我们的应用程序是否正在运行。在本部分中,我们将创建一个就绪运行状况检查,该检查将能够判断我们的应用程序是否能够处理请求。

我们将创建另一个运行状况检查程序,用于模拟与外部服务提供商(例如数据库)的连接。对于初学者,我们将始终返回指示应用程序已就绪的响应。

创建 org.acme.microprofile.health.DatabaseConnectionHealthCheck 类:

package org.acme.microprofile.health;

import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Readiness;

import jakarta.enterprise.context.ApplicationScoped;

@Readiness
@ApplicationScoped
public class DatabaseConnectionHealthCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.up("Database connection health check");
    }
}

如果您现在在 http://localhost:8080/q/health/live 再次运行运行状况检查,checks 数组将仅包含先前定义的 SimpleHealthCheck,因为它是由 @Liveness 限定符定义的唯一检查。然而,如果您访问 http://localhost:8080/q/health/ready(在浏览器中或通过 curl [role="bare"]http://localhost:8080/q/health/ready),您将只看到 Database connection health check,因为它是用 @Readiness 限定符定义的唯一运行状况检查,即就绪运行状况检查程序。

如果您访问 http://localhost:8080/q/health,您将返回两个检查。

MicroProfile Health 规范中详细说明了在何种情况下应使用哪些运行状况检查程序。通常,活动程序确定是否应重新启动应用程序,而就绪程序确定是否可以联系应用程序并提出请求。

Adding a startup health check procedure

第三个也是最后一种类型的运行状况检查程序是启动。启动程序被定义为缓慢启动容器的选项(在 Quarkus 中不需要),以延迟活动探测的调用,该调用将从启动首次响应 UP 时接管启动。启动运行状况检查使用 @Startup 限定符定义。

请确保导入 microprofile org.eclipse.microprofile.health.Startup 注释,因为它与 io.quarkus.runtime.Startup 发生了不幸的冲突。

创建 org.acme.microprofile.health.StartupHealthCheck 类:

package org.acme.microprofile.health;

import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Startup;

import jakarta.enterprise.context.ApplicationScoped;

@Startup
@ApplicationScoped
public class StartupHealthCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.up("Startup health check");
    }
}

启动运行状况检查可以在 http://localhost:8080/q/health/started 或与 http://localhost:8080/q/health 处的其他运行状况检查程序一起使用。

Negative health check procedures

在本部分中,我们会将 Database connection health check 扩展为有选项来声明我们的应用程序尚未准备好处理请求,因为无法建立基础数据库连接。为了简单起见,我们仅通过配置属性确定是否可以访问数据库。

更新 org.acme.microprofile.health.DatabaseConnectionHealthCheck 类:

package org.acme.microprofile.health;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
import org.eclipse.microprofile.health.Readiness;

import jakarta.enterprise.context.ApplicationScoped;

@Readiness
@ApplicationScoped
public class DatabaseConnectionHealthCheck implements HealthCheck {

    @ConfigProperty(name = "database.up", defaultValue = "false")
    private boolean databaseUp;

    @Override
    public HealthCheckResponse call() {

        HealthCheckResponseBuilder responseBuilder = HealthCheckResponse.named("Database connection health check");

        try {
            simulateDatabaseConnectionVerification();
            responseBuilder.up();
        } catch (IllegalStateException e) {
            // cannot access the database
            responseBuilder.down();
        }

        return responseBuilder.build();
    }

    private void simulateDatabaseConnectionVerification() {
        if (!databaseUp) {
            throw new IllegalStateException("Cannot contact database");
        }
    }
}

到目前为止,我们使用了一种简化的方法,即通过 HealthCheckResponse#up(String) 来构建 HealthCheckResponse(还有 HealthCheckResponse#down(String)),它将直接构建响应对象。从现在开始,我们利用 HealthCheckResponseBuilder 类提供的完整构建器功能。

如果您现在重新运行就绪性运行状况检查(在 http://localhost:8080/q/health/ready),总体 status 将会是 DOWN(已关闭)。您也可以检查 http://localhost:8080/q/health/live 的可用性检查,它将返回总体 status 的 UP(已启动),因为它不受就绪性检查影响。

由于我们不应该让此应用程序的可用性检查处于 DOWN(关闭)状态,并且由于我们在 dev 模式中运行 Quarkus,您可以在 src/main/resources/application.properties 中向 database.up=true 添加起来并重新运行可用性运行状况检查——它应该会再次处于 up(已启动)状态。

Adding user-specific data to the health check response

在前面的章节中,我们看到了如何使用最小的属性(即运行状况检查名称及其状态(UP(已启动)或 DOWN(关闭)))来创建简单的运行状况检查。但是,MicroProfile 运行状况规范还提供了一种方法,用于允许应用程序使用发送到使用端点形式的键值对提供任意数据。这可以通过使用运行状况检查响应构建器 API 的 withData(key, value) 方法来完成。

让我们创建一个新的运行状况检查过程 org.acme.microprofile.health.DataHealthCheck

package org.acme.microprofile.health;

import org.eclipse.microprofile.health.Liveness;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

import jakarta.enterprise.context.ApplicationScoped;

@Liveness
@ApplicationScoped
public class DataHealthCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {
        return HealthCheckResponse.named("Health check with data")
                .up()
                .withData("foo", "fooValue")
                .withData("bar", "barValue")
                .build();
    }
}

如果您通过访问 /q/health/live 端点重新运行可用性运行状况检查过程,您便可以看到新的运行状况检查 Health check with data 存在于 checks 数组中。此检查包含一个名为 data 的新属性,它是一个 JSON 对象,由我们在运行状况检查过程中定义的属性组成。

此功能在故障场景中特别有用,您可以在其中将错误与运行状况检查响应一起传递。

        try {
            simulateDatabaseConnectionVerification();
            responseBuilder.up();
        } catch (IllegalStateException e) {
            // cannot access the database
            responseBuilder.down()
                    .withData("error", e.getMessage()); // pass the exception message
        }

Context propagation into the health check invocations

出于性能原因,上下文(例如,CDI 或安全上下文)不会传播到每个运行状况检查调用中。但是,如果您需要启用此功能,您可以设置 config 属性 quarkus.smallrye-health.context-propagation=true,以允许上下文传播到每个运行状况检查调用中。

Reactive health checks

MicroProfile Health 目前不支持返回反应类型,但 SmallRye Health 支持。

如果您希望提供一个反应型运行状况检查,则可以实现 io.smallrye.health.api.AsyncHealthCheck 接口,而不是 org.eclipse.microprofile.health.HealthCheck 接口。 io.smallrye.health.api.AsyncHealthCheck 接口允许您返回一个 Uni<HealthCheckResponse>

以下示例显示了一个反应型可用性检查:

import io.smallrye.health.api.AsyncHealthCheck;

import org.eclipse.microprofile.health.Liveness;
import org.eclipse.microprofile.health.HealthCheckResponse;

import jakarta.enterprise.context.ApplicationScoped;

@Liveness
@ApplicationScoped
public class LivenessAsync implements AsyncHealthCheck {

    @Override
    public Uni<HealthCheckResponse> call() {
        return Uni.createFrom().item(HealthCheckResponse.up("liveness-reactive"))
                .onItem().delayIt().by(Duration.ofMillis(10));
    }
}

Extension health checks

某些扩展可能提供默认运行状况检查,包括该扩展会自动注册其运行状况检查。

例如,用于管理 Quarkus 数据源的 quarkus-agroal 会自动注册一个可用性运行状况检查,该检查会验证每个数据源: Datasource Health Check

您可以通过属性 quarkus.health.extensions.enabled 禁用扩展运行状况检查,因此不会自动注册任何检查。

Health UI

实验性 - 未包含在 MicroProfile 规范中

health-ui 允许您在 Web GUI 中查看您的运行状况检查。

Quarkus smallrye-health 扩展附带 health-ui,并在 dev 和 test 模式下默认启用它,但也可以在生产模式下显式配置。

health-ui 可以从 [role="bare"][role="bare"]http://localhost:8080/q/health-ui/ 访问。

health ui screenshot01

Management interface

默认情况下,运行状况检查会在主 HTTP 服务器上公开。您可以通过在应用程序配置中设置 quarkus.management.enabled=true 在一个单独的网络接口和端口上公开它们。请注意,此属性是一个构建时属性。该值无法在运行时重写。

如果你在未自定义管理网络接口和端口的情况下启用管理接口,则会在以下位置公开运行状况检查:http://0.0.0.0:9000/q/health。你可以使用 quarkus.smallrye-health.root-path 属性配置 path(前一个 URL 中的 health 段)。

请参阅 management interface reference 了解更多信息。

Conclusion

SmallRye Health 为你的应用程序提供了一种方法来分发关于其运行状况状态的信息,以表明它是否能够正常工作。可用性检查用来判断是否应重新启动应用程序,而就绪性检查用来判断应用程序是否能够处理请求。

在 Quarkus 中启用 SmallRye Health 功能所需的一切包括:

  • 使用 quarkus-maven-pluginsmallrye-health Quarkus 扩展添加到你的项目:include::./_includes/devtools/extension-add.adoc[]:!devtools-wrapped:

  • 或只需添加以下 Maven 依赖项:[source, xml] .pom.xml

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-health</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-smallrye-health")

Configuration Reference

Unresolved include directive in modules/ROOT/pages/smallrye-health.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-smallrye-health_quarkus.smallrye-health.adoc[]