SmallRye Health

本指南演示了 Quarkus 应用程序如何使用 SmallRye Health MicroProfile Health规范的实现。

This guide demonstrates how your Quarkus application can use SmallRye Health an implementation of the MicroProfile Health specification.

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

SmallRye Health allows applications to provide information about their state to external viewers which is typically useful in cloud environments where automated processes must be able to determine whether the application should be discarded or restarted.

Prerequisites

Unresolved directive in smallrye-health.adoc - include::{includes}/prerequisites.adoc[]

Architecture

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

In this guide, we build a simple REST application that exposes MicroProfile Health functionalities at the /q/health/live and /q/health/ready endpoints according to the specification.

Solution

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

We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.

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

Clone the Git repository: git clone {quickstarts-clone-url}, or download an {quickstarts-archive-url}[archive].

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

The solution is located in the microprofile-health-quickstart {quickstarts-tree-url}/microprofile-health-quickstart[directory].

Creating the Maven Project

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

First, we need a new project. Create a new project with the following command:

Unresolved directive in smallrye-health.adoc - include::{includes}/devtools/create-app.adoc[]

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

This command generates a project, importing the smallrye-health extension.

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

If you already have your Quarkus project configured, you can add the smallrye-health extension to your project by running the following command in your project base directory:

Unresolved directive in smallrye-health.adoc - include::{includes}/devtools/extension-add.adoc[]

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

This will add the following to your build file:

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 端点:

Importing the smallrye-health extension directly exposes three REST endpoints:

  • /q/health/live - The application is up and running.

  • /q/health/ready - The application is ready to serve requests.

  • /q/health/started - The application is started.

  • /q/health - Accumulating all health check procedures in the application.

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

To check that the smallrye-health extension is working as expected:

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

All health REST endpoints return a simple JSON object with two fields:

  • status — the overall result of all the health check procedures

  • checks — an array of individual checks

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

The general status of the health check is computed as a logical AND of all the declared health check procedures. The checks array is empty as we have not specified any health check procedure yet so let’s define some.

Management interface

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

By default, the health checks are exposed on the main HTTP server. You can expose them on a separate network interface and port by enabling the management interface with the quarkus.management.enabled=true property. Refer to the management interface reference for more information.

Creating your first health check

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

In this section, we create our first simple health check procedure.

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

Create the org.acme.microprofile.health.SimpleHealthCheck class:

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 It’s recommended to annotate the health check class with @ApplicationScoped or the @Singleton scope so that a single bean instance is used for all health check requests.
2 If a bean class annotated with one of the health check annotations declares no scope then the @Singleton scope is used automatically.

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

As you can see, the health check procedures are defined as CDI beans that implement the HealthCheck interface and are annotated with one of the health check qualifiers, such as:

  • @Liveness - the liveness check accessible at /q/health/live

  • @Readiness - the readiness check accessible at /q/health/ready

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

HealthCheck is a functional interface whose single method call returns a HealthCheckResponse object which can be easily constructed by the fluent builder API shown in the example.

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

As we have started our Quarkus application in dev mode simply repeat the request to http://localhost:8080/q/health/live by refreshing your browser window or by using curl [role="bare"]http://localhost:8080/q/health/live. Because we defined our health check to be a liveness procedure (with @Liveness qualifier) the new health check procedure is now present in the checks array.

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

Congratulations! You’ve created your first Quarkus health check procedure. Let’s continue by exploring what else can be done with SmallRye Health.

Adding a readiness health check procedure

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

In the previous section, we created a simple liveness health check procedure which states whether our application is running or not. In this section, we will create a readiness health check which will be able to state whether our application is able to process requests.

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

We will create another health check procedure that simulates a connection to an external service provider such as a database. For starters, we will always return the response indicating the application is ready.

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

Create org.acme.microprofile.health.DatabaseConnectionHealthCheck class:

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 限定符定义的唯一运行状况检查,即就绪运行状况检查程序。

If you now rerun the health check at http://localhost:8080/q/health/live the checks array will contain only the previously defined SimpleHealthCheck as it is the only check defined with the @Liveness qualifier. However, if you access http://localhost:8080/q/health/ready (in the browser or with curl [role="bare"]http://localhost:8080/q/health/ready) you will see only the Database connection health check as it is the only health check defined with the @Readiness qualifier as the readiness health check procedure.

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

If you access http://localhost:8080/q/health you will get back both checks.

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

More information about which health check procedures should be used in which situation is detailed in the MicroProfile Health specification. Generally, the liveness procedures determine whether the application should be restarted while readiness procedures determine whether it makes sense to contact the application with requests.

Adding a startup health check procedure

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

The third and final type of health check procedures is startup. Startup procedures are defined as an option for slow starting containers (should not be needed in Quarkus) to delay the invocations of liveness probe which will take over from startup once the startup responds UP for the first time. Startup health checks are defined with the @Startup qualifier.

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

Please make sure that you import the microprofile org.eclipse.microprofile.health.Startup annotation since there is an unfortunate clash with io.quarkus.runtime.Startup.

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

Create org.acme.microprofile.health.StartupHealthCheck class:

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 处的其他运行状况检查程序一起使用。

The startup health check will be available either at http://localhost:8080/q/health/started or together with other health check procedure at http://localhost:8080/q/health.

Negative health check procedures

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

In this section, we extend our Database connection health check with the option of stating that our application is not ready to process requests as the underlying database connection cannot be established. For simplicity reasons, we only determine whether the database is accessible or not by a configuration property.

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

Update the org.acme.microprofile.health.DatabaseConnectionHealthCheck class:

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 类提供的完整构建器功能。

Until now, we used a simplified method of building a HealthCheckResponse through the HealthCheckResponse#up(String) (there is also HealthCheckResponse#down(String)) which will directly build the response object. From now on, we utilize the full builder capabilities provided by the HealthCheckResponseBuilder class.

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

If you now rerun the readiness health check (at http://localhost:8080/q/health/ready) the overall status should be DOWN. You can also check the liveness check at http://localhost:8080/q/health/live which will return the overall status UP because it isn’t influenced by the readiness checks.

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

As we shouldn’t leave this application with a readiness check in a DOWN state and because we are running Quarkus in dev mode you can add database.up=true in src/main/resources/application.properties and rerun the readiness health check again — it should be up again.

Adding user-specific data to the health check response

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

In previous sections, we saw how to create simple health checks with only the minimal attributes, namely, the health check name and its status (UP or DOWN). However, the MicroProfile Health specification also provides a way for the applications to supply arbitrary data in the form of key-value pairs sent to the consuming end. This can be done by using the withData(key, value) method of the health check response builder API.

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

Let’s create a new health check procedure 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 对象,由我们在运行状况检查过程中定义的属性组成。

If you rerun the liveness health check procedure by accessing the /q/health/live endpoint you can see that the new health check Health check with data is present in the checks array. This check contains a new attribute called data which is a JSON object consisting of the properties we have defined in our health check procedure.

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

This functionality is specifically useful in failure scenarios where you can pass the error along with the health check response.

        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,以允许上下文传播到每个运行状况检查调用中。

For performance reasons, the context (e.g., CDI or security context) is not propagated into each health check invocation. However, if you need to enable this functionality you can set the config property quarkus.smallrye-health.context-propagation=true to allow the context propagation into every health check call.

Reactive health checks

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

MicroProfile Health currently doesn’t support returning reactive types, but SmallRye Health does.

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

If you want to provide a reactive health check, you can implement the io.smallrye.health.api.AsyncHealthCheck interface instead of the org.eclipse.microprofile.health.HealthCheck one. The io.smallrye.health.api.AsyncHealthCheck interface allows you to return a Uni<HealthCheckResponse>.

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

The following example shows a reactive liveness check:

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

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

Some extension may provide default health checks, including the extension will automatically register its health checks.

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

For example, quarkus-agroal that is used to manage Quarkus datasource(s) automatically register a readiness health check that will validate each datasource: Datasource Health Check.

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

You can disable extension health checks via the property quarkus.health.extensions.enabled so none will be automatically registered.

Health UI

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

Experimental - not included in the MicroProfile specification

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

health-ui allows you to see your Health Checks in a Web GUI.

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

The Quarkus smallrye-health extension ships with health-ui and enables it by default in dev and test modes, but it can also be explicitly configured for production mode as well.

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

health-ui can be accessed from [role="bare"]http://localhost:8080/q/health-ui/ .

health ui screenshot01

Management interface

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

By default, the health checks are exposed on the main HTTP server. You can expose them on a separate network interface and port by setting quarkus.management.enabled=true in your application configuration. Note that this property is a build-time property. The value cannot be overridden at runtime.

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

If you enable the management interface without customizing the management network interface and port, the health checks are exposed under: http://0.0.0.0:9000/q/health. You can configure the path (the health segment in the previous URL) using the quarkus.smallrye-health.root-path property.

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

Refer to the management interface reference for more information.

Conclusion

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

SmallRye Health provides a way for your application to distribute information about its healthiness state to state whether it is able to function properly. Liveness checks are utilized to tell whether the application should be restarted and readiness checks are used to tell whether the application is able to process requests.

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

All that is needed to enable the SmallRye Health features in Quarkus is:

  • adding the smallrye-health Quarkus extension to your project using the quarkus-maven-plugin:[.iokays-translated-db02e3f4cea5eb0c86c0d7b256651d57] include::{includes}/devtools/extension-add.adoc[]:!devtools-wrapped:

Unresolved directive in smallrye-health.adoc - include::{includes}/devtools/extension-add.adoc[] :!devtools-wrapped: * or simply adding the following Maven dependency:[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 directive in smallrye-health.adoc - include::{generated-dir}/config/quarkus-smallrye-health_quarkus.smallrye-health.adoc[]