git clone https://github.com/openliberty/guide-microprofile-health.git
cd guide-microprofile-health
Adding health reports to microservices
Prerequisites:
Explore how to report and check the health of a microservice with MicroProfile Health.
What you’ll learn
You will learn how to use MicroProfile Health to report the health status of microservices and take appropriate actions based on this report.
MicroProfile Health allows services to report their health, and it publishes the overall health status to a defined endpoint. A service reports UP
if it is available and reports DOWN
if it is unavailable. MicroProfile Health reports an individual service status at the endpoint and indicates the overall status as UP
if all the services are UP
. A service orchestrator can then use the health statuses to make decisions.
A service checks its own health by performing necessary self-checks and then reports its overall status by implementing the API provided by MicroProfile Health. A self-check can be a check on anything that the service needs, such as a dependency, a successful connection to an endpoint, a system property, a database connection, or the availability of required resources. MicroProfile offers checks for both liveness and readiness.
You will add liveness and readiness checks to the system
and inventory
services, which are provided for you, and implement what is necessary to report health status by using MicroProfile Health.
Getting started
The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:
The start
directory contains the starting project that you will build upon.
The finish
directory contains the finished project that you will build.
Try what you’ll build
The finish
directory in the root of this guide contains the finished application. Give it a try before you proceed.
To try out the application, first go to the finish
directory and run the following Maven goal to build the application and deploy it to Open Liberty:
cd finish
mvn liberty:run
After you see the following message, your application server is ready:
The defaultServer server is ready to run a smarter planet.
The system
and inventory
services can be found at the following URLs:
Visit the http://localhost:9080/health URL to see the overall health status of the application, as well as the aggregated data of the liveness and readiness checks. Two checks show the state of the system
service, and the other two checks show the state of the inventory
service. As you might expect, both services are in the UP
state, and the overall health status of the application is in the UP
state.
You can also access the /health/ready
endpoint by visiting the http://localhost:9080/health/ready URL to view the data from the readiness health checks. Similarly, access the /health/live
endpoint by visiting the http://localhost:9080/health/live URL to view the data from the liveness health checks.
After you are finished checking out the application, stop the Open Liberty server by pressing CTRL+C
in the command-line session where you ran the server. Alternatively, you can run the liberty:stop
goal from the finish
directory in another shell session:
mvn liberty:stop
Adding health checks to microservices
Navigate to the start
directory to begin.
When you run Open Liberty in development mode, known as dev mode, the server listens for file changes and automatically recompiles and deploys your updates whenever you save a new change. Run the following goal to start Open Liberty in dev mode:
mvn liberty:dev
After you see the following message, your application server in dev mode is ready:
Press the Enter key to run tests on demand.
Dev mode holds your command-line session to listen for file changes. Open another command-line session to continue, or open the project in your editor.
A health report will be generated automatically for all services that enable MicroProfile Health. The mpHealth
feature has already been enabled for you in the src/main/liberty/config/server.xml
file.
All services must provide an implementation of the HealthCheck
interface, which will be used to verify their health. MicroProfile Health offers health checks for both readiness and liveness. A readiness check allows third-party services, such as Kubernetes, to determine whether a microservice is ready to process requests. For example, a readiness check might check dependencies, such as database connections. A liveness check allows third-party services to determine whether a microservice is running. If the liveness check fails, the application can be terminated. For example, a liveness check might fail if the application runs out of memory.
server.xml
1<server description="Sample Liberty server">
2
3 <featureManager>
4 <feature>jaxrs-2.1</feature>
5 <feature>jsonp-1.1</feature>
6 <feature>cdi-2.0</feature>
7 <feature>mpConfig-1.4</feature>
8 <feature>mpRestClient-1.4</feature>
9 <!-- tag::mpHealth[] -->
10 <feature>mpHealth-2.2</feature>
11 <!-- end::mpHealth[] -->
12 </featureManager>
13
14 <variable name="default.http.port" defaultValue="9080"/>
15 <variable name="default.https.port" defaultValue="9443"/>
16
17 <httpEndpoint host="*" httpPort="${default.http.port}"
18 httpsPort="${default.https.port}" id="defaultHttpEndpoint"/>
19
20 <webApplication location="guide-microprofile-health.war" contextRoot="/"/>
21</server>
Adding health checks to the system service
Create theSystemReadinessCheck
class.src/main/java/io/openliberty/guides/system/SystemReadinessCheck.java
SystemReadinessCheck.java
The @Readiness
annotation indicates that this particular bean is a readiness health check procedure. By pairing this annotation with the ApplicationScoped
context from the Contexts and Dependency Injections API, the bean is discovered automatically when the http://localhost:9080/health endpoint receives a request.
The call()
method is used to return the health status of a particular service. In this case, you are simply checking if the server name is defaultServer
and returning UP
if it is, and DOWN
otherwise. Overall, this is a very simple implementation of the call()
method. In a real environment, you would want to orchestrate more meaningful health checks.
Create theSystemLivenessCheck
class.src/main/java/io/openliberty/guides/system/SystemLivenessCheck.java
SystemLivenessCheck.java
The @Liveness
annotation indicates that this is a liveness health check procedure. In this case, you are checking the heap memory usage. If more than 90% of the maximum memory is being used, a status of DOWN
is returned.
Adding health checks to the inventory service
Create theInventoryReadinessCheck
class.src/main/java/io/openliberty/guides/inventory/InventoryReadinessCheck.java
InventoryReadinessCheck.java
In the isHealthy()
method, you report the inventory
service as not ready if the service is in maintenance or if its dependant service is unavailable.
For simplicity, the custom io_openliberty_guides_inventory_inMaintenance
MicroProfile Config property, which is defined in the resources/CustomConfigSource.json
file, is used to indicate whether the service is in maintenance. This file was already created for you.
Moreover, the readiness health check procedure makes an HTTP GET
request to the system
service and checks its status. If the request is successful, the inventory
service is healthy and ready because its dependant service is available. Otherwise, the inventory
service is not ready and an unhealthy readiness status is returned.
If you are curious about the injected inventoryConfig
object or if you want to learn more about MicroProfile Config, see Configuring microservices.
Create theInventoryLivenessCheck
class.src/main/java/io/openliberty/guides/inventory/InventoryLivenessCheck.java
InventoryLivenessCheck.java
As with the system
liveness check, you are checking the heap memory usage. If more than 90% of the maximum memory is being used, a DOWN
status is returned.
CustomConfigSource.json
1{
2 "config_ordinal":700,
3 "io_openliberty_guides_inventory_inMaintenance":false
4}
Running the application
You started the Open Liberty server in dev mode at the beginning of the guide, so all the changes were automatically picked up.
While the server is running, navigate to the http://localhost:9080/health URL to find the aggregated liveness and readiness health reports on the two services.
You can also navigate to the http://localhost:9080/health/ready URL to view the readiness health report, or the http://localhost:9080/health/live URL to view the liveness health report.
Put the inventory
service in maintenance by setting the io_openliberty_guides_inventory_inMaintenance
property to true
in the resources/CustomConfigSource.json
file. Because this configuration file is picked up dynamically, simply refresh the http://localhost:9080/health URL to see that the state of the inventory
service changed to DOWN
. The overall state of the application also changed to DOWN
as a result. Go to the http://localhost:9080/inventory/systems URL to verify that the inventory
service is indeed in maintenance. Set the io_openliberty_guides_inventory_inMaintenance
property back to false
after you are done.
CustomConfigSource.json
1{
2 "config_ordinal":700,
3 "io_openliberty_guides_inventory_inMaintenance":false
4}
Testing health checks
You will implement several test methods to validate the health of the system
and inventory
services.
Create theHealthIT
class.src/test/java/it/io/openliberty/guides/health/HealthIT.java
HealthIT.java
Let’s break down the test cases:
The
testIfServicesAreUp()
test case compares the generated health report with the actual status of the services.The
testReadiness()
test case compares the generated health report for the readiness checks with the actual status of the services.The
testLiveness()
test case compares the generated health report for the liveness checks with the actual status of the services.The
testIfInventoryServiceIsDown()
test case puts theinventory
service in maintenance by setting theio_openliberty_guides_inventory_inMaintenance
property totrue
and comparing the generated health report with the actual status of the services.
A few more tests were included to verify the basic functionality of the system
and inventory
services. They can be found under the src/test/java/it/io/openliberty/guides/inventory/InventoryEndpointIT.java
and src/test/java/it/io/openliberty/guides/system/SystemEndpointIT.java
files. If a test failure occurs, then you might have introduced a bug into the code. These tests run automatically as a part of the integration test suite.
CustomConfigSource.json
1{
2 "config_ordinal":700,
3 "io_openliberty_guides_inventory_inMaintenance":false
4}
InventoryEndpointIT.java
SystemEndpointIT.java
Running the tests
Because you started Open Liberty in dev mode, press the enter/return
key to run the tests.
You see the following output:
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running it.io.openliberty.guides.health.HealthIT
[INFO] [WARNING ] CWMH0052W: The class com.ibm.ws.microprofile.health.impl.HealthCheckResponseImpl implementing HealthCheckResponse in the guide-microprofile-health application in module guide-microprofile-health.war, reported a DOWN status with data Optional[{}].
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.463 s - in it.io.openliberty.guides.health.HealthIT
[INFO] Running it.io.openliberty.guides.system.SystemEndpointIT
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 s - in it.io.openliberty.guides.system.SystemEndpointIT
[INFO] Running it.io.openliberty.guides.inventory.InventoryEndpointIT
[INFO] [WARNING ] Interceptor for {http://client.inventory.guides.openliberty.io/}SystemClient has thrown exception, unwinding now
[INFO] Could not send Message.
[INFO] [err] The specified host is unknown.
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.102 s - in it.io.openliberty.guides.inventory.InventoryEndpointIT
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
The warning messages are expected. The first warning results from a request to a service that is under maintenance. This request is made in the testIfInventoryServiceIsDown()
test from the InventoryEndpointIT
integration test. The second warning and error results from a request to a bad or an unknown hostname. This request is made in the testUnknownHost()
test from the InventoryEndpointIT
integration test.
To see whether the tests detect a failure, manually change the configuration of io_openliberty_guides_inventory_inMaintenance
from false
to true
in the resources/CustomConfigSource.json
file. Rerun the tests to see a test failure occur. The test failure occurs because the initial status of the inventory
service is DOWN
.
When you are done checking out the service, exit dev mode by pressing CTRL+C
in the command-line session where you ran the server, or by typing q
and then pressing the enter/return
key.
Great work! You’re done!
You just learned how to add health checks to report the states of microservices by using MicroProfile Health in Open Liberty. Then, you wrote tests to validate the generated health report.
Feel free to try one of the related MicroProfile guides. They demonstrate additional technologies that you can learn and expand on top of what you built here.
Guide Attribution
Adding health reports to microservices by Open Liberty is licensed under CC BY-ND 4.0
Prerequisites:
Nice work! Where to next?
What did you think of this guide?




Thank you for your feedback!
What could make this guide better?
Raise an issue to share feedback
Create a pull request to contribute to this guide
Need help?
Ask a question on Stack Overflow