Health Checks — Telling the Platform You Are Well
At 3 a.m. the PostgreSQL server behind library-service restarts. The app is still running, but every borrow request fails. Should the platform keep sending it traffic? A good health endpoint answers that question honestly, so machines can react before people have to.
The rule
Health rolls up: if any vital part is down, the whole app reports down.
/actuator/health gathers the results of many health indicators, one per dependency. Boot adds them automatically: a database indicator when there is a DataSource, a disk-space indicator, and others for Redis, MongoDB and so on. Each reports a status:
UP— working.DOWN— broken.OUT_OF_SERVICE— deliberately taken out of use.UNKNOWN— cannot tell.
The endpoint combines them, and the worst status wins, in the order DOWN, then OUT_OF_SERVICE, then UP. UNKNOWN counts for least, so a mix of UP and UNKNOWN still reports UP. UP answers with HTTP 200; DOWN and OUT_OF_SERVICE answer with 503 Service Unavailable, which is exactly what load balancers look for.
By default the response shows only the overall status. To see each part:
management.endpoint.health.show-details=when-authorizedThe values are never (the default), when-authorized (logged-in users with the right role) and always.
You can add your own indicator. library-service depends on an external catalogue service for book covers:
@Component
public class CatalogueHealthIndicator implements HealthIndicator {
private final CatalogueClient catalogue;
public CatalogueHealthIndicator(CatalogueClient catalogue) { this.catalogue = catalogue; }
@Override
public Health health() {
return catalogue.ping()
? Health.up().build()
: Health.down().withDetail("reason", "catalogue not responding").build();
}
}It appears in the details under the name catalogue: the class name minus the HealthIndicator suffix, starting lower-case.
On Kubernetes, Boot also offers two narrower groups: /actuator/health/liveness ("is the process stuck and in need of a restart?") and /actuator/health/readiness ("should it receive traffic right now?"). They switch on automatically when Boot detects Kubernetes, or with management.endpoint.health.probes.enabled=true.
The shortcut
To predict the overall answer, find the worst status in the list; that is the app's status, and it decides 200 or 503. Then ask whether that part should really decide it.
Collect the parts
db: DOWN.diskSpace: UP.catalogue: UP.
The trap is making a non-essential part decide health. If book covers are nice to have, a failing catalogue indicator would take a working library offline. Leave such an indicator out of the readiness group (health groups let you choose which indicators each group includes), or report the problem as a detail instead of DOWN.
Drills
Answer fast — trust the rule.
The indicators report db: UP, diskSpace: DOWN, catalogue: UP. What is the overall status?
Which HTTP status does /actuator/health return when the app is DOWN?
A class is named CatalogueHealthIndicator. Under which name does it appear in the health details?
Which probe should fail when the app must be restarted because it is stuck?
Remember
- Health rolls up: if any vital part is down, the whole app reports down.
- Find the worst status; UP means 200, DOWN means 503.
- Trap: letting a nice-to-have dependency take a working app out of service.
