Spring Boot Health Check — Complete Implementation Guide
In this tutorial, you will learn about Spring Boot Health Check. We cover key concepts, practical examples, and best practices to help you master this topic.
Spring Boot Actuator provides built-in health check endpoints that automatically detect available dependencies like databases, caches, and message brokers, with extensible health indicators for custom components.
What You'll Learn
By the end of this tutorial, you will know how to configure Spring Boot Actuator health checks, create custom health indicators, set up liveness and readiness probes, and integrate with Kubernetes.
Why It Matters
Spring Boot is the most popular Java framework for Microservices. Actuator health checks are the standard way to expose health information for Spring Boot applications in production.
Real-World Use
Durga Antivirus Pro's scanning API is built with Spring Boot. Its health endpoint checks the signature database, virus definition cache, and file storage service, reporting detailed status for each.
Spring Boot Health Check Learning Path
flowchart LR
A[Go Health Check] --> B[Spring Boot Health Check]
B --> C[Actuator Setup]
B --> D[Custom Indicators]
B --> E[Kubernetes Probes]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Actuator Configuration
Spring Boot Actuator health endpoints require minimal configuration.
# application.yml
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: always
show-components: always
probes:
enabled: true
health:
readinessstate:
enabled: true
livenessstate:
enabled: true
// No code needed for the basic health endpoint
// The /actuator/health endpoint is auto-configured
// GET /actuator/health
// {
// "status": "UP",
// "components": {
// "db": { "status": "UP", "details": { "database": "PostgreSQL", "validationQuery": "isValid()" } },
// "diskSpace": { "status": "UP", "details": { "total": 1000000, "free": 500000 } },
// "ping": { "status": "UP" }
// }
// }
Custom Health Indicator
Create custom health indicators for application-specific dependencies.
package com.dodatech.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class SignatureDatabaseHealthIndicator implements HealthIndicator {
private final RestTemplate restTemplate;
public SignatureDatabaseHealthIndicator(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public Health health() {
try {
var response = restTemplate.getForEntity(
"https://signatures.dodatech.com/health",
String.class
);
if (response.getStatusCode().is2xxSuccessful()) {
return Health.up()
.withDetail("service", "signature-database")
.withDetail("latencyMs", "15")
.build();
}
return Health.down()
.withDetail("service", "signature-database")
.withDetail("statusCode", response.getStatusCodeValue())
.build();
} catch (Exception e) {
return Health.down(e)
.withDetail("service", "signature-database")
.build();
}
}
}
Liveness and Readiness Probes
Spring Boot 3 provides dedicated health groups for Kubernetes probes.
# application.yml
management:
endpoint:
health:
probes:
enabled: true
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
// Liveness probe endpoint: /actuator/health/liveness
// Returns 200 if the application is internally healthy
// Returns 503 if the application needs restarting
// Readiness probe endpoint: /actuator/health/readiness
// Returns 200 if the application is ready to serve traffic
// Returns 503 if the application is not ready (e.g., during startup or dependency failure)
@Configuration
public class ProbeConfiguration {
@Bean
public HealthIndicator databaseReadinessIndicator(DataSource dataSource) {
return () -> {
try (var connection = dataSource.getConnection()) {
if (connection.isValid(2)) {
return Health.up().build();
}
return Health.down().withDetail("reason", "Database connection invalid").build();
} catch (Exception e) {
return Health.down(e).build();
}
};
}
}
Composite Health Indicator
Group multiple related health checks into a composite indicator.
@Component
public class CacheLayerHealthIndicator implements HealthIndicator {
private final List<CacheHealthChecker> checkers;
public CacheLayerHealthIndicator(List<CacheHealthChecker> checkers) {
this.checkers = checkers;
}
@Override
public Health health() {
var builder = Health.up();
boolean allHealthy = true;
for (var checker : checkers) {
try {
var result = checker.check();
if (!result.isHealthy()) {
allHealthy = false;
}
builder.withDetail(checker.getName(), result);
} catch (Exception e) {
allHealthy = false;
builder.withDetail(checker.getName(), "error: " + e.getMessage());
}
}
return allHealthy ? builder.build() : builder.down().build();
}
interface CacheHealthChecker {
String getName();
CacheCheckResult check();
}
record CacheCheckResult(boolean isHealthy, long latencyMs) {}
}
Health Endpoint Security
Configure security for health endpoints in production.
// SecurityConfiguration.java
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health/**").permitAll()
.requestMatchers("/actuator/info").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
// application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
roles: ADMIN
Common Mistakes
Exposing all Actuator endpoints in production -- /actuator/env, /actuator/configprops, and /actuator/beans can leak sensitive information. Only expose health and info in production.
Not setting show-details properly -- show-details: always reveals dependency details to anyone. Use show-details: when-authorized with appropriate roles in production.
Forgetting to enable probes -- In Spring Boot 3, liveness and readiness probes are disabled by default. Set management.endpoint.health.probes.enabled: true.
Making health indicators throw exceptions -- Health indicators should catch all exceptions and return Health.down(), not throw. An uncaught exception makes the entire health endpoint fail.
Not testing custom health indicators -- Custom indicators have bugs too. Write unit tests that verify they return Up, Down, and Unknown status correctly.
Practice Questions
What dependency is needed for Spring Boot Actuator health checks? spring-boot-starter-actuator. It auto-configures the health endpoint and built-in health indicators.
How do you create a custom health indicator? Implement the HealthIndicator interface and register it as a Spring bean. The health() method returns a Health object.
What is the difference between LivenessStateHealthIndicator and ReadinessStateHealthIndicator? Liveness indicates the application is internally healthy and doesn't need restarting. Readiness indicates the application can serve traffic.
Challenge: Implement a health indicator that aggregates multiple sub-checks and reports degraded status if any sub-check fails.
@Component
public class AggregatedHealthIndicator implements HealthIndicator {
private final List<HealthIndicator> indicators;
public AggregatedHealthIndicator(List<HealthIndicator> indicators) {
this.indicators = indicators;
}
@Override
public Health health() {
var builder = Health.up();
int up = 0, down = 0;
for (var indicator : indicators) {
try {
var health = indicator.health();
if (health.getStatus() == Status.UP) {
up++;
} else {
down++;
}
} catch (Exception e) {
down++;
}
}
builder.withDetail("up", up);
builder.withDetail("down", down);
return down == 0 ? builder.build() : builder.down().build();
}
}
FAQ
Mini Project
Build a Spring Boot application with Actuator health checks, custom health indicators for database and external API, liveness and readiness probe endpoints, and proper security configuration.
@SpringBootApplication
public class HealthCheckApplication {
public static void main(String[] args) {
SpringApplication.run(HealthCheckApplication.class, args);
}
@Bean
public HealthIndicator customCheck() {
return () -> Health.up()
.withDetail("service", "custom")
.withDetail("version", "1.0.0")
.build();
}
}
What's Next
Now that you understand Spring Boot health checks, learn about Kubernetes probe configuration. Then explore custom health indicators in depth.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro