All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mp.health.adoc Maven / Gradle / Ivy

///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2020, 2024 Oracle and/or its affiliates.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= MicroProfile Health
:spec-name: MicroProfile Health
:description: {spec-name} support in Helidon MP
:keywords: helidon, mp, microprofile, health
:feature-name: MicroProfile Health
:microprofile-bundle: true
:rootdir: {docdir}/..

include::{rootdir}/includes/mp.adoc[]

== Contents

- <>
- <>
- <>
- <>
- <>
- <>
- <>

== Overview

Microservices expose their health status primarily so external tools (for example, an orchestrator such as Kubernetes)
can monitor each service and take action, such as restarting a service instance if it has failed
or temporarily shunting traffic away from the instance if the service is unable to process
incoming requests normally.


== Maven Coordinates [[Maven-Coordinates]]

To enable MicroProfile Health add the xref:introduction/microprofile.adoc[helidon-microprofile bundle]  dependency to your project's `pom.xml` (see xref:../about/managing-dependencies.adoc[Managing Dependencies]).

[source,xml]
----

    io.helidon.microprofile.bundles
    helidon-microprofile

----

MicroProfile Health is already included in the bundle.

If full control over the dependencies is required, and you want to minimize the quantity of the dependencies - `Helidon MicroProfile Core budnle` should be used. In this case the following dependencies should be included in your project's `pom.xml`:

[source,xml]
----

    io.helidon.microprofile.bundles
    helidon-microprofile-core

----

[source,xml]
----

    io.helidon.microprofile.health
    helidon-microprofile-health

----

To enable built-in health checks add the following dependency
(or use the xref:introduction/microprofile.adoc[helidon-microprofile bundle] )

//tag::built-in-health-checks-depc[]
[source,xml]
----

    io.helidon.health
    helidon-health-checks

----
//end::built-in-health-checks-depc[]

== Usage

Helidon implements link:{microprofile-health-spec-url}[MicroProfile Health] Specification.
The spec prescribes how external tools probe a service's health checks and how you
implement health checks as part of your microservice that are specific to your service's needs.

=== Concepts - Liveness, Readiness, and Startup Checks

MicroProfile Health supports three types of health checks:

* _Liveness_ checks report whether the runtime environment in which the service is running
is sufficient to support the work the service performs.
The environment is beyond the control of
the service itself and typically cannot improve without outside intervention.
If a microservice instance reports a `DOWN`
liveness check, it should never report `UP` later.
It will need to be stopped and a replacement instance created.

* _Readiness_ checks report whether the service is _currently_ capable of performing its work.
A service that reports `DOWN` for its readiness cannot _at the moment_ do its job, but at
some future point it might become able to do so without requiring a restart.

* _Startup_ checks indicate whether the service has started to the point where liveness and readiness checks even make sense.
A service reporting `DOWN` for a startup check is still initializing itself and normally will report `UP` soon, assuming it is able to start successfully.


== REST Endpoints [[Rest-Endpoints]]
A MicroProfile-compliant service reports its health via known REST endpoints. Helidon MP
provides these endpoints automatically as part of every MP microservice that includes health support..

External management tools (or `curl` or browsers) retrieve health checks using the REST endpoints in the table below which summarizes the types of health checks in MicroProfile Health.
Responses from the health endpoints report `200` (OK), `204` (no content), or `503` (service unavailable) depending on the outcome of running the health checks.
HTTP `GET` responses include JSON content showing the detailed results of all the health checks which the server executed after receiving the request.
HTTP `HEAD` requests return only the status with no payload.


.Types of Health Checks
|===
|Type | Meaning | REST endpoint | Kubernetes response on failure

|liveness
|whether the runtime environment is suitable
|`/health/live`
|Restarts container.

|readiness
|whether the microservice is currently capable of doing its work
|`/health/ready`
|Diverts requests away from the instance; periodically rechecks readiness and resumes traffic once the
microservice reports itself as ready.

|startup
|whether the microservice has initialized to the point where liveness and readiness checks might pass
|`/health/started`
|Treats the instance as still starting up; does not check liveness or readiness until the startup probe reports success or times out according to its configuration.
|===


== Configuration

Health checks may be configured using the following properties.

The class responsible for configuration is:

include::{rootdir}/config/io_helidon_webserver_observe_health_HealthObserver.adoc[leveloffset=+1,tag=config]

Properties may be set in `application.yaml` or in `microprofile-config.properties`, in both cases using the `health` prefix.

For example, you can specify a custom port and root context for the root health endpoint path.
However, you cannot use different ports, such as http://localhost:8080/myhealth and http://localhost:8081/myhealth/live.
Likewise, you cannot use different paths, such as http://localhost:8080/health and http://localhost:8080/probe/live.
The example below will change the root path.
[source,properties]
.Create a file named `microprofile-config.properties` in the `resources/META-INF` directory with the following contents:
----
health.endpoint=/myhealth  #<1>
----
<1> The `endpoint` setting specifies the root path for the health endpoint.

== Examples

Generate Helidon MP Quickstart project following these xref:guides/quickstart.adoc[instructions].

=== Using the Built-In Health Checks

Helidon has a set of built-in health checks that can report various
conditions:

* deadlock detection
* available disk space
* available heap memory

The following example will demonstrate how to use the built-in health checks.  These examples are all executed
from the root directory of your project (helidon-quickstart-mp).

[source,xml]
.Include the built-in health checks dependency in your `pom.xml`:
include::{rootdir}/mp/health.adoc[tag=built-in-health-checks-depc]

[source,bash]
.Build the application, then run it:
----
mvn package
java -jar target/helidon-quickstart-mp.jar
----

[source,bash]
.Verify the health endpoint in a new terminal window:
----
curl http://localhost:8080/health
----

[source,json]
.JSON response:
----
{
  "status": "UP",
  "checks": [
    {
      "name": "deadlock",
      "status": "UP"
    },
    {
      "name": "diskSpace",
      "status": "UP",
      "data": {
        "free": "325.54 GB",
        "freeBytes": 349543358464,
        "percentFree": "69.91%",
        "total": "465.63 GB",
        "totalBytes": 499963174912
      }
    },
    {
      "name": "heapMemory",
      "status": "UP",
      "data": {
        "free": "230.87 MB",
        "freeBytes": 242085696,
        "max": "3.56 GB",
        "maxBytes": 3817865216,
        "percentFree": "98.90%",
        "total": "271.00 MB",
        "totalBytes": 284164096
      }
    }
  ]
}
----

=== Custom Liveness Health Checks

You can create application-specific custom health checks and integrate them with Helidon
using CDI.  The following example shows how to add a custom liveness health check.

[source,java]
.Create a new `GreetLivenessCheck` class with the following content:
----
include::{sourcedir}/mp/HealthSnippets.java[tag=snippet_1, indent=0]
----
<1> Annotation indicating this is a liveness health check.
<2> Annotation indicating this is a bean instantiated once per application (in Helidon this means just once per runtime).
<3> Build the HealthCheckResponse with status `UP` and the current time.

[source,bash]
.Build and run the application, then verify the custom liveness health endpoint:
----
curl http://localhost:8080/health/live
----

[source,json]
.JSON response:
----
{
  "status": "UP",
  "checks": [
    {
      "name": "LivenessCheck",
      "status": "UP",
      "data": {
        "time": 1566338255331
      }
    }
  ]
}
----

=== Custom Readiness Health Checks

You can add a readiness check to indicate that the application is ready to be used.  In this
example, the server will wait five seconds before it becomes ready.

[source,java]
.Create a new `GreetReadinessCheck` class with the following content:
----
include::{sourcedir}/mp/HealthSnippets.java[tag=snippet_2, indent=0]
----
<1> Annotation indicating that this is a readiness health check.
<2> Build the `HealthCheckResponse` with status `UP` after five seconds, else `DOWN`.
<3> Record the time at startup.
<4> Become ready after 5 seconds.

[source,bash]
.Build and run the application. Issue the curl command with -v within five seconds and you will see that the application is not ready:
----
curl -v  http://localhost:8080/health/ready
----

[source]
.HTTP response status
----
< HTTP/1.1 503 Service Unavailable // <1>
----
<1> The HTTP status is `503` since the application is not ready.

[source,json]
.JSON response:
----
{
  "status": "DOWN",
  "checks": [
    {
      "name": "ReadinessCheck",
      "status": "DOWN",
      "data": {
        "time": 1566399775700
      }
    }
  ]
}
----

[source,bash]
.After five seconds you will see the application is ready:
----
curl -v http://localhost:8080/health/ready
----

[source]
.HTTP response status
----
< HTTP/1.1 200 OK // <1>
----
<1> The HTTP status is `200` indicating that the application is ready.

[source,json]
.JSON response:
----
{
  "status": "UP",
  "checks": [
    {
      "name": "ReadinessCheck",
      "status": "UP",
      "data": {
        "time": 1566399775700
      }
    }
  ]
}
----

Full example code is available link:{helidon-github-tree-url}/examples/microprofile[here].

=== Custom Startup Health Checks

You can add a startup check to indicate whether or not the application has initialized to the point that the other health checks make sense.
In this example, the server will wait eight seconds before it declares itself started.

[source,java]
.Create a new `GreetStartedCheck` class with the following content:
----
include::{sourcedir}/mp/HealthSnippets.java[tag=snippet_3, indent=0]
----
<1> Annotation indicating that this is a startup health check.
<2> Build the `HealthCheckResponse` with status `UP` after eight seconds, else `DOWN`.
<3> Record the time at startup of Helidon; the application will declare itself as started eight seconds later.
<4> Become ready after 5 seconds.

[source,bash]
.Build and run the application.  Issue the curl command with -v within five seconds and you will see that the application has not yet started:
----
curl -v  http://localhost:8080/health/started
----

[source]
.HTTP response status:
----
< HTTP/1.1 503 Service Unavailable // <1>
----
<1> The HTTP status is `503` since the application has not started.


[source,json]
.JSON response:
----
{
  "status": "DOWN",
  "checks": [
    {
      "name": "StartedCheck",
      "status": "DOWN",
      "data": {
        "time": 1566399775700
      }
    }
  ]
}
----

[source,bash]
.After eight seconds you will see the application has started:
----
curl -v http://localhost:8080/health/started
----

[source]
.HTTP response status:
----
< HTTP/1.1 200 OK // <1>
----
<1> The HTTP status is `200` indicating that the application is started.

[source,json]
.JSON response:
----
{
  "status": "UP",
  "checks": [
    {
      "name": "StartedCheck",
      "status": "UP",
      "data": {
        "time": 1566399775700
      }
    }
  ]
}
----

When using the health check URLs, you can get the following health check data:

* liveness only - http://localhost:8080/health/live
* readiness only -  http://localhost:8080/health/ready
* startup checks only - http://localhost:8080/health/started
* all health check data -  http://localhost:8080/health

[source,bash]
.Get all the health check data, including custom data:
----
curl http://localhost:8080/health
----

[source,json]
.JSON response:
----
{
  "status": "UP",
  "checks": [
    {
      "name": "LivenessCheck",
      "status": "UP",
      "data": {
        "time": 1566403431536
      }
    }
  ]
}
----

Full example code is available link:{helidon-github-tree-url}/examples/microprofile[here].

== Reference

* link:{javadoc-base-url}/io.helidon.microprofile.health/module-summary.html[Helidon MicroProfile Health JavaDoc]
* link:{javadoc-base-url}/io.helidon.health.checks/module-summary.html[Helidon Built-in Checks JavaDoc]
* link:{microprofile-health-spec-url}[MicroProfile Health Specification]
* link:https://github.com/eclipse/microprofile-health[MicroProfile Health on GitHub]




© 2015 - 2025 Weber Informatics LLC | Privacy Policy