本文目录导读:

我来为您提供一个完整的Java健康检查案例,包含多种实现方式。
基础健康检查(使用Spring Boot Actuator)
Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件 application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
probes:
enabled: true
health:
db:
enabled: true
redis:
enabled: true
自定义健康检查指示器
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// 模拟数据库健康检查
boolean isDatabaseUp = checkDatabaseConnection();
if (isDatabaseUp) {
return Health.up()
.withDetail("database", "MySQL")
.withDetail("status", "connected")
.build();
} else {
return Health.down()
.withDetail("database", "MySQL")
.withDetail("status", "disconnected")
.build();
}
} catch (Exception e) {
return Health.down(e)
.withDetail("error", e.getMessage())
.build();
}
}
private boolean checkDatabaseConnection() {
// 实际的数据库连接检查逻辑
return true;
}
}
自定义服务健康检查
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import java.net.HttpURLConnection;
import java.net.URL;
@Component
public class ExternalServiceHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
URL url = new URL("https://api.example.com/health");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(3000);
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
return Health.up()
.withDetail("service", "External API")
.withDetail("responseCode", responseCode)
.build();
} else {
return Health.down()
.withDetail("service", "External API")
.withDetail("responseCode", responseCode)
.build();
}
} catch (Exception e) {
return Health.down(e)
.withDetail("service", "External API")
.withDetail("error", e.getMessage())
.build();
}
}
}
自定义健康检查服务
健康检查核心服务
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HealthCheckService {
private static final Logger logger = LoggerFactory.getLogger(HealthCheckService.class);
private final Map<String, HealthStatus> healthStatusMap = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 健康状态枚举
public enum HealthStatus {
UP, DOWN, DEGRADED, UNKNOWN
}
// 健康检查结果类
public static class HealthResult {
private final HealthStatus status;
private final Map<String, Object> details;
private final long timestamp;
public HealthResult(HealthStatus status, Map<String, Object> details) {
this.status = status;
this.details = details;
this.timestamp = System.currentTimeMillis();
}
public HealthStatus getStatus() {
return status;
}
public Map<String, Object> getDetails() {
return details;
}
public long getTimestamp() {
return timestamp;
}
}
// 注册健康检查器
public void registerChecker(String name, Checkable checker) {
healthStatusMap.put(name, HealthStatus.UNKNOWN);
scheduler.scheduleAtFixedRate(() -> {
HealthResult result = performCheck(name, checker);
updateHealthStatus(name, result);
}, 0, 30, TimeUnit.SECONDS); // 每30秒执行一次
}
// 执行健康检查
private HealthResult performCheck(String name, Checkable checker) {
try {
checker.check();
return new HealthResult(HealthStatus.UP, Map.of("lastCheck", System.currentTimeMillis()));
} catch (Exception e) {
logger.error("Health check failed for: {}", name, e);
return new HealthResult(HealthStatus.DOWN,
Map.of("error", e.getMessage(), "lastCheck", System.currentTimeMillis()));
}
}
// 更新健康状态
private void updateHealthStatus(String name, HealthResult result) {
healthStatusMap.put(name, result.getStatus());
if (result.getStatus() == HealthStatus.DOWN) {
// 发送告警通知
sendAlert(name, result);
}
}
// 获取所有健康状态
public Map<String, HealthStatus> getAllHealthStatus() {
return new ConcurrentHashMap<>(healthStatusMap);
}
// 获取特定服务健康状态
public HealthStatus getHealthStatus(String serviceName) {
return healthStatusMap.getOrDefault(serviceName, HealthStatus.UNKNOWN);
}
// 查询整体健康状态
public boolean isSystemHealthy() {
return !healthStatusMap.containsValue(HealthStatus.DOWN);
}
// 发送告警
private void sendAlert(String serviceName, HealthResult result) {
// 实现邮件、短信、Webhook等告警通知
logger.warn("Service {} is down: {}", serviceName, result.getDetails());
}
// 关闭资源
public void shutdown() {
scheduler.shutdown();
}
// 健康检查接口
public interface Checkable {
void check() throws Exception;
}
}
具体健康检查实现
// 数据库健康检查
@Component
public class DatabaseHealthChecker implements HealthCheckService.Checkable {
@Autowired
private DataSource dataSource;
@Override
public void check() throws Exception {
try (Connection conn = dataSource.getConnection()) {
if (conn.isValid(5)) {
return;
}
throw new Exception("Database connection is invalid");
}
}
}
// Redis健康检查
@Component
public class RedisHealthChecker implements HealthCheckService.Checkable {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public void check() throws Exception {
try {
String result = redisTemplate.opsForValue().get("health_check_key");
// 可以执行PING命令验证Redis连接
if (result == null) {
redisTemplate.opsForValue().set("health_check_key", "ok", Duration.ofSeconds(10));
}
} catch (Exception e) {
throw new Exception("Redis connection failed", e);
}
}
}
// 磁盘空间检查
@Component
public class DiskSpaceHealthChecker implements HealthCheckService.Checkable {
@Override
public void check() throws Exception {
File root = new File("/");
long freeSpace = root.getUsableSpace();
long totalSpace = root.getTotalSpace();
double usageRatio = 1.0 - (double) freeSpace / totalSpace;
if (usageRatio > 0.9) {
throw new Exception("Disk usage > 90%");
}
}
}
// 内存使用检查
@Component
public class MemoryHealthChecker implements HealthCheckService.Checkable {
@Override
public void check() throws Exception {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
double memoryUsage = (double) usedMemory / maxMemory;
if (memoryUsage > 0.85) {
throw new Exception("Memory usage > 85%");
}
}
}
RESTful健康检查接口
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/health")
public class HealthController {
@Autowired
private HealthCheckService healthCheckService;
@GetMapping("/check")
public Map<String, Object> checkHealth() {
Map<String, Object> result = new HashMap<>();
result.put("status", healthCheckService.isSystemHealthy() ? "UP" : "DOWN");
result.put("services", healthCheckService.getAllHealthStatus());
result.put("timestamp", System.currentTimeMillis());
return result;
}
@GetMapping("/service/{name}")
public Map<String, Object> checkServiceHealth(@PathVariable String name) {
Map<String, Object> result = new HashMap<>();
result.put("service", name);
result.put("status", healthCheckService.getHealthStatus(name));
result.put("timestamp", System.currentTimeMillis());
return result;
}
}
Docker健康检查配置
FROM openjdk:11-jre-slim COPY target/app.jar app.jar # Dockerfile中使用HEALTHCHECK指令 HEALTHCHECK --interval=30s --timeout=5s --start-period=60s \ CMD curl -f http://localhost:8080/api/health/check || exit 1 EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
配置文件
server:
port: 8080
app:
health-check:
enabled: true # 是否启用健康检查
interval: 30 # 检查间隔(秒)
timeout: 5 # 超时时间(秒)
alert-enabled: true # 是否启用告警
alert-webhook: "https://hooks.example.com/alerts"
健康检查工具类
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
public class JVMHealthUtils {
public static Map<String, Object> getJVMStats() {
Map<String, Object> stats = new HashMap<>();
// 内存统计
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
stats.put("heap_used", formatBytes(memoryMXBean.getHeapMemoryUsage().getUsed()));
stats.put("heap_max", formatBytes(memoryMXBean.getHeapMemoryUsage().getMax()));
stats.put("non_heap_used", formatBytes(memoryMXBean.getNonHeapMemoryUsage().getUsed()));
// CPU使用
OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
stats.put("cpu_cores", osMXBean.getAvailableProcessors());
stats.put("system_load_average", osMXBean.getSystemLoadAverage());
// 线程统计
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
stats.put("thread_count", threadMXBean.getThreadCount());
stats.put("daemon_thread_count", threadMXBean.getDaemonThreadCount());
stats.put("peak_thread_count", threadMXBean.getPeakThreadCount());
stats.put("total_started_thread_count", threadMXBean.getTotalStartedThreadCount());
// JVM信息
Runtime runtime = Runtime.getRuntime();
stats.put("total_memory", formatBytes(runtime.totalMemory()));
stats.put("free_memory", formatBytes(runtime.freeMemory()));
stats.put("used_memory", formatBytes(runtime.totalMemory() - runtime.freeMemory()));
return stats;
}
private static String formatBytes(long bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String pre = "KMGTPE".charAt(exp - 1) + "B";
return String.format("%.1f %s", bytes / Math.pow(1024, exp), pre);
}
}
使用示例
@Component
public class HealthCheckDemo {
@Autowired
private HealthCheckService healthCheckService;
@Autowired
private DatabaseHealthChecker databaseHealthChecker;
@Autowired
private RedisHealthChecker redisHealthChecker;
@PostConstruct
public void init() {
// 注册健康检查器
healthCheckService.registerChecker("database", databaseHealthChecker);
healthCheckService.registerChecker("redis", redisHealthChecker);
healthCheckService.registerChecker("disk", new DiskSpaceHealthChecker());
}
}
这个完整的健康检查案例包括了:
- Spring Boot Actuator 集成的健康检查
- 自定义健康检查服务,支持定时检查和多种检查器
- RESTful API 暴露健康检查接口
- Docker 健康检查配置
- JVM 统计工具类
- 丰富的健康指标:数据库、Redis、磁盘、内存、CPU等
可根据实际需求选择合适的实现方式。