Jeff Walker
Jeff Walker

Reputation: 1704

Proper way to get Spring Boot health status from inside

I have an external requirement that I provide an endpoint to tell the load balancer to send traffic to my app. Much like the Kubernetes "readiness" probe, but it has to be a certain format and path, so I can just give them the actuator health endpoint.

In the past I've used the HealthEndpoint and called health(), but that doesn't work for reactive apps. Is there a more flexible way to see if the app is "UP"? At this level I don't care if it's reactive or servlet, I just want to know what Spring Boot says about the app.

I haven't found anything like this, most articles talk about calling /actuator/health, but that isn't what I need.


Edit:

Just a bit more detail, I have to return a certain string "NS_ENABLE" if it's good. There are certain conditions where I return "NS_DISABLE", so I can't just not return anything, which would normally make sense.

Also, I really like how Spring Boot does the checking for me. I'd rather not re-implement all those checks.


Edit 2: My final solution

The answers below got me very far along even though it wasn't my final solution, so I wanted to give a hint to my final understanding.

It turns out that the HealthEndpoint works for reactive apps just as well as servlet apps, you just have to wrap them in Mono.

Upvotes: 5

Views: 14677

Answers (3)

sonus21
sonus21

Reputation: 5388

How do we define health of any web servers? We look at how our dependent services are, we check the status of Redis, MySQL, MongoDB, ElasticSearch, and other databases, this's what actuator does internally.

Actuator checks the status of different databases and based on that it returns Up/Down.

You can implement your own methods that would check the health of dependent services.

  • Redis is healthy or not can be checked using ping command
  • MySQL can be verified using SELECT 1 command or run some query that should always success like SHOW TABLES

Similarly, you can implement a health check for other services. If you find all required services are up then you can declare up otherwise down.

What about shutdown triggers? Whenever your server receives a shutdown signal than no matter what's the state of your dependent services, you should always say down, so that upstream won't send a call to this instance.


Edit

The health of the entire spring app can be checked programmatically by autowiring one or more beans from the Actuator module.

@Controller
public class MyHealthController{
 @Autowired private HealthEndpoint healthEndpoint;
 @GetMapping("health")
  public Health health() {
    Health health = healthEndpoint.health();
    return healthEndpoint.health();
  }
}

There're other beans related to health check, we can auto wire required beans. Some of the beans provide the health of the respective component, we can combine the health of each component using HealthAggregator to get the final Health. All registered health indicator components can be accessed via HealthIndicatorRegistry.

@Controller
public class MyHealthController{
  @Autowired private HealthAggregator healthAggregator;
  @Autowired private HealthIndicatorRegistry healthIndicatorRegistry;

  @GetMapping("health")
  public Health health() {
    Map<String, Health> health = new HashMap<>();
    for (Entry<String, HealthIndicator> entry : healthIndicatorRegistry.getAll().entrySet()) {
      health.put(entry.getKey(), entry.getValue().health());
    }
    return healthAggregator.aggregate(health);
  }
}

  

NOTE: Reactive component has its own health indicator. Useful classes are ReactiveHealthIndicatorRegistry, ReactiveHealthIndicator etc

Upvotes: 6

Mike Jarsoon
Mike Jarsoon

Reputation: 179

Here's the spring boot documentation on writing reactive health endpoints. Folow the guide and should be enough for your usecase.

They also document on how to write liveliness and Readiness of your application.

https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#reactive-health-indicators

Upvotes: 0

Chetan Laddha
Chetan Laddha

Reputation: 1005

Simple solution is to write your own health endpoint instead of depending on Spring. Spring Boot provides you production-ready endpoints but if it doesn't satisfy your purpose, write your end-point. It will just return "UP" in response. If the service is down, it will not return anything.

Upvotes: -1

Related Questions