编辑此页面

SmallRye 健康检查

本指南演示了您的 Quarkus 应用程序如何使用 SmallRye Health,它是 MicroProfile Health 规范的一个实现。

SmallRye Health 允许应用程序向外部查看者提供有关其状态的信息,这在云环境中通常很有用,在这些环境中,自动化流程必须能够确定是否应丢弃或重新启动应用程序。

先决条件

要完成本指南,您需要

  • 大约 15 分钟

  • 一个 IDE

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

  • Apache Maven 3.9.9

  • 如果您想使用它,可以选择 Quarkus CLI

  • 如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置

架构

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

解决方案

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

克隆 Git 存储库:git clone https://github.com/quarkusio/quarkus-quickstarts.git,或下载 存档

解决方案位于 microprofile-health-quickstart 目录中。

创建 Maven 项目

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

CLI
quarkus create app org.acme:microprofile-health-quickstart \
    --extension='smallrye-health' \
    --no-code
cd microprofile-health-quickstart

要创建 Gradle 项目,请添加 --gradle--gradle-kotlin-dsl 选项。

有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.24.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=microprofile-health-quickstart \
    -Dextensions='smallrye-health' \
    -DnoCode
cd microprofile-health-quickstart

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

对于 Windows 用户

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

  • 如果使用 Powershell,请将 -D 参数用双引号引起来,例如 "-DprojectArtifactId=microprofile-health-quickstart"

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

如果您已经配置了 Quarkus 项目,则可以通过在项目基本目录中运行以下命令将 smallrye-health 扩展添加到项目中

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

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

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

运行健康检查

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

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

  • /q/health/ready - 应用程序已准备好为请求提供服务。

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

  • /q/health - 累积应用程序中的所有健康检查过程。

要检查 smallrye-health 扩展是否按预期工作

所有 health REST 端点都返回一个简单的 JSON 对象,其中包含两个字段

  • status — 所有健康检查过程的总体结果

  • checks — 单个检查的数组

健康检查的总体 status 计算为所有声明的健康检查过程的逻辑 AND。由于我们尚未指定任何健康检查过程,因此 checks 数组为空,因此让我们定义一些。

管理界面

默认情况下,健康检查在主 HTTP 服务器上公开。您可以通过启用管理界面并设置 quarkus.management.enabled=true 属性,将它们公开在单独的网络接口和端口上。有关更多信息,请参阅管理界面参考

创建您的第一个健康检查

在本节中,我们将创建我们的第一个简单的健康检查过程。

创建 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 作用域。

如您所见,健康检查过程被定义为 CDI bean,这些 bean 实现 HealthCheck 接口,并使用健康检查限定符之一进行注释,例如

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

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

HealthCheck 是一个函数式接口,它的单个方法 call 返回一个 HealthCheckResponse 对象,该对象可以通过示例中显示的 fluent builder API 轻松构建。

由于我们已在开发模式下启动了 Quarkus 应用程序,只需通过刷新浏览器窗口或使用 curl https://:8080/q/health/live 重复请求 https://:8080/q/health/live。因为我们将健康检查定义为活跃性过程(使用 @Liveness 限定符),所以新的健康检查过程现在存在于 checks 数组中。

恭喜!您已经创建了您的第一个 Quarkus 健康检查过程。让我们继续探索 SmallRye Health 还可以做什么。

添加就绪性健康检查过程

在上一节中,我们创建了一个简单的活跃性健康检查过程,用于说明我们的应用程序是否正在运行。在本节中,我们将创建一个就绪性健康检查,该检查能够说明我们的应用程序是否能够处理请求。

我们将创建另一个健康检查过程,该过程模拟与外部服务提供商(例如数据库)的连接。对于初学者,我们将始终返回响应,指示应用程序已准备好。

创建 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");
    }
}

如果您现在重新运行 https://:8080/q/health/live 上的健康检查,则 checks 数组将仅包含先前定义的 SimpleHealthCheck,因为它是使用 @Liveness 限定符定义的唯一检查。但是,如果您访问 https://:8080/q/health/ready(在浏览器中或使用 curl https://:8080/q/health/ready),您将只看到 Database connection health check,因为它是使用 @Readiness 限定符定义的唯一健康检查作为就绪性健康检查过程。

如果您访问 https://:8080/q/health,您将获得两个检查。

MicroProfile Health 规范中详细介绍了在哪些情况下应使用哪些健康检查过程的更多信息。通常,活跃性过程确定是否应重新启动应用程序,而就绪性过程确定通过请求联系应用程序是否有意义。

添加启动健康检查过程

第三种也是最后一种类型的健康检查过程是启动。启动过程被定义为慢速启动容器的一个选项(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");
    }
}

启动健康检查将在 https://:8080/q/health/started 或与其他健康检查过程一起在 https://:8080/q/health 上可用。

负面健康检查过程

在本节中,我们将扩展我们的 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#down(String))构建 HealthCheckResponse,这将直接构建响应对象。从现在开始,我们将利用 HealthCheckResponseBuilder 类提供的完整构建器功能。

如果您现在重新运行就绪性健康检查(在 https://:8080/q/health/ready),则总体 status 应为 DOWN。您还可以在 https://:8080/q/health/live 检查活跃性检查,这将返回总体 status UP,因为它不受就绪性检查的影响。

由于我们不应将此应用程序的就绪性检查保持在 DOWN 状态,并且因为我们正在开发模式下运行 Quarkus,您可以在 src/main/resources/application.properties 中添加 database.up=true 并再次重新运行就绪性健康检查 — 它应该再次启动。

将用户特定数据添加到健康检查响应

在前面的章节中,我们了解了如何创建仅具有最小属性(即健康检查名称及其状态(UP 或 DOWN))的简单健康检查。但是,MicroProfile Health 规范还提供了一种方式,供应用程序以键值对的形式向使用者发送任意数据。这可以通过使用健康检查响应构建器 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
        }

将上下文传播到健康检查调用中

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

响应式健康检查

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));
    }
}

健康状态更改观察者

如果您需要对应用程序的健康状态更改做出反应,则 Smallrye Health 扩展提供了一个 CDI 事件,可以通知您有关各个健康状态更改。

要观察健康状态更改,您可以使用标准 CDI 观察机制观察 io.smallrye.health.api.event.HealthStatusChangeEvent。由于我们不能保证观察者方法始终在工作线程上运行(这意味着它可以在事件循环线程上运行),因此建议您永远不要在观察者方法中阻塞。

import io.smallrye.health.api.event.HealthStatusChangeEvent;

@ApplicationScoped
public class HealthObserver {

    public void observeHealthChange(@Observes @Default HealthStatusChangeEvent event) {
        ...
    }

    public void observeReadinessChange(@Observes @Readiness HealthStatusChangeEvent event) {
        ...
    }

    public void observeLivenessChange(@Observes @Liveness HealthStatusChangeEvent event) {
        ...
    }
}

扩展健康检查

某些扩展可能会提供默认健康检查,包括扩展会自动注册其健康检查。

例如,用于管理 Quarkus 数据源的 quarkus-agroal 会自动注册一个就绪性健康检查,该检查将验证每个数据源:数据源健康检查

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

健康检查 UI

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

health-ui 允许您在 Web GUI 中查看您的健康检查。

Quarkus smallrye-health 扩展附带 health-ui,并且默认情况下在开发和测试模式下启用它,但也可以显式配置为生产模式。

可以从 https://:8080/q/health-ui/ 访问 health-ui

Health UI

管理界面

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

如果您启用管理界面而不自定义管理网络接口和端口,则健康检查将在以下位置公开:http://0.0.0.0:9000/q/health。您可以使用 quarkus.smallrye-health.root-path 属性配置路径(先前 URL 中的 health 段)。

有关更多信息,请参阅管理界面参考

结论

SmallRye Health 为您的应用程序提供了一种分发有关其健康状态的信息的方式,以说明它是否能够正常运行。活跃性检查用于判断是否应重新启动应用程序,而就绪性检查用于判断应用程序是否能够处理请求。

要在 Quarkus 中启用 SmallRye Health 功能,只需

  • 使用 quarkus-maven-pluginsmallrye-health Quarkus 扩展添加到您的项目中

    CLI
    quarkus extension add smallrye-health
    Maven
    ./mvnw quarkus:add-extension -Dextensions='smallrye-health'
    Gradle
    ./gradlew addExtension --extensions='smallrye-health'
  • 或者只需添加以下 Maven 依赖项

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

配置参考

构建时固定的配置属性 - 所有其他配置属性都可以在运行时覆盖

配置属性

类型

默认

激活或禁用此扩展。禁用此扩展意味着不公开任何与健康相关的信息。

环境变量:QUARKUS_SMALLRYE_HEALTH_ENABLED

显示更多

布尔值

true

是否应启用扩展发布的健康检查。

环境变量:QUARKUS_SMALLRYE_HEALTH_EXTENSIONS_ENABLED

显示更多

布尔值

true

是否在生成的 OpenAPI 文档中包含活跃性和就绪性健康端点

环境变量:QUARKUS_SMALLRYE_HEALTH_OPENAPI_INCLUDED

显示更多

布尔值

false

健康检查端点的根路径。默认情况下,此值将被解析为相对于 ${quarkus.http.non-application-root-path} 的路径。如果启用了管理界面,则该值将被解析为相对于 ${quarkus.management.root-path} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_ROOT_PATH

显示更多

字符串

health

活跃性健康检查端点的相对路径。默认情况下,此值将被解析为相对于 ${quarkus.smallrye-health.rootPath} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_LIVENESS_PATH

显示更多

字符串

live

就绪性健康检查端点的相对路径。默认情况下,此值将被解析为相对于 ${quarkus.smallrye-health.rootPath} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_READINESS_PATH

显示更多

字符串

ready

健康组端点的相对路径。默认情况下,此值将被解析为相对于 ${quarkus.smallrye-health.rootPath} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_GROUP_PATH

显示更多

字符串

group

健康状况良好检查端点的相对路径。默认情况下,此值将被解析为相对于 ${quarkus.smallrye-health.rootPath} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_WELLNESS_PATH

显示更多

字符串

well

启动健康检查端点的相对路径。默认情况下,此值将被解析为相对于 ${quarkus.smallrye-health.rootPath} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_STARTUP_PATH

显示更多

字符串

started

是否应将上下文传播到每个健康检查调用。

环境变量:QUARKUS_SMALLRYE_HEALTH_CONTEXT_PROPAGATION

显示更多

布尔值

false

可以创建的最大健康组数。

环境变量:QUARKUS_SMALLRYE_HEALTH_MAX_GROUP_REGISTRIES_COUNT

显示更多

整数

在健康检查上未定义其他健康组时使用的默认健康组的名称。

环境变量:QUARKUS_SMALLRYE_HEALTH_DEFAULT_HEALTH_GROUP

显示更多

字符串

如果启用了管理界面,则健康端点和 UI 将在管理界面下发布。这允许您通过将该值设置为 false 来将健康检查排除在管理之外

环境变量:QUARKUS_SMALLRYE_HEALTH_MANAGEMENT_ENABLED

显示更多

布尔值

true

指定报告的 DOWN 响应是否应与 RFC 9457 - HTTP API 的问题详细信息对齐。

环境变量:QUARKUS_SMALLRYE_HEALTH_INCLUDE_PROBLEM_DETAILS

显示更多

布尔值

false

是否应启用健康检查 UI。默认情况下,如果包含健康检查 UI(请参阅 always-include),则启用它。

环境变量:QUARKUS_SMALLRYE_HEALTH_UI_ENABLE

显示更多

布尔值

true

要包含在结果 JSON 对象中的其他顶级属性。

环境变量:QUARKUS_SMALLRYE_HEALTH_ADDITIONAL_PROPERTY__PROPERTY_NAME_

显示更多

Map<String,String>

是否应启用 HealthCheck。

环境变量:QUARKUS_SMALLRYE_HEALTH_CHECK__CHECK_CLASSNAME__ENABLED

显示更多

布尔值

false

SmallRye Health UI 配置

类型

默认

健康检查 UI 可用的路径。不允许使用值 /,因为它会阻止应用程序提供任何其他内容。默认情况下,此值将被解析为相对于 ${quarkus.http.non-application-root-path} 的路径。

环境变量:QUARKUS_SMALLRYE_HEALTH_UI_ROOT_PATH

显示更多

字符串

health-ui

始终包含 UI。默认情况下,这仅包含在开发和测试中。将此设置为 true 还将在生产环境中包含 UI

环境变量:QUARKUS_SMALLRYE_HEALTH_UI_ALWAYS_INCLUDE

显示更多

布尔值

false

相关内容