erp-java/nacos/examples/HealthCheckConfig.java

124 lines
4.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.erp.common.nacos;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.api.common.pojo.Instance;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistration;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Nacos健康检查配置
*
* Nacos 2.x 支持多种健康检查类型:
* 1. TCP - 检测端口是否可连接
* 2. HTTP - 发送HTTP请求检测
* 3. MYSQL - 检测MySQL连接
* 4. NONE - 不健康不摘除
*
* 默认使用Spring Boot Actuator的/health端点作为健康检查
*/
@Slf4j
@Component("nacosHealthIndicator")
public class NacosHealthCheckConfig implements HealthIndicator {
private final NacosDiscoveryProperties nacosDiscoveryProperties;
@Value("${spring.application.name:unknown}")
private String serviceName;
// 存储服务状态实际生产中由Nacos服务端维护
private static final Map<String, Boolean> SERVICE_HEALTH_STATUS = new ConcurrentHashMap<>();
public NacosHealthCheckConfig(NacosDiscoveryProperties nacosDiscoveryProperties) {
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
}
@Override
public Health health() {
// 1. 检查Nacos连接
if (!isNacosReachable()) {
return Health.down()
.withDetail("nacos", "无法连接到Nacos服务器")
.build();
}
// 2. 检查实例是否已注册
if (!isInstanceRegistered()) {
return Health.down()
.withDetail("registration", "实例未注册到Nacos")
.build();
}
// 3. 检查本地健康状态
if (!isLocalHealthy()) {
return Health.down()
.withDetail("local", "本地健康检查失败")
.build();
}
// 4. 获取实例元数据
Map<String, String> metadata = nacosDiscoveryProperties.getInstanceMetadataMap();
return Health.up()
.withDetail("service", serviceName)
.withDetail("instanceId", nacosDiscoveryProperties.getInstanceId())
.withDetail("namespace", nacosDiscoveryProperties.getNamespace())
.withDetail("group", nacosDiscoveryProperties.getGroup())
.withDetail("metadata", metadata)
.withDetail("nacos", "连接正常")
.build();
}
private boolean isNacosReachable() {
try {
// 简单连通性检查
return true; // 实际生产中应该尝试连接
} catch (Exception e) {
log.error("Nacos连接检查失败", e);
return false;
}
}
private boolean isInstanceRegistered() {
return nacosDiscoveryProperties.getInstanceId() != null;
}
private boolean isLocalHealthy() {
// 这里可以添加自定义健康检查逻辑
// 例如检查数据库连接、Redis连接、MQ连接等
return SERVICE_HEALTH_STATUS.getOrDefault(serviceName, true);
}
/**
* 更新服务健康状态(可被外部调用)
*/
public void setHealthy(String serviceName, boolean healthy) {
SERVICE_HEALTH_STATUS.put(serviceName, healthy);
log.info("更新服务健康状态: service={}, healthy={}", serviceName, healthy);
}
/**
* 获取当前服务的所有实例健康状态
*/
public void logAllInstancesHealth() {
log.info("========== 服务实例健康状态 ==========");
log.info("服务: {}", serviceName);
log.info("命名空间: {}", nacosDiscoveryProperties.getNamespace());
log.info("分组: {}", nacosDiscoveryProperties.getGroup());
log.info("实例ID: {}", nacosDiscoveryProperties.getInstanceId());
log.info("实例IP: {}", nacosDiscoveryProperties.getIp());
log.info("实例端口: {}", nacosDiscoveryProperties.getPort());
log.info("元数据: {}", nacosDiscoveryProperties.getInstanceMetadataMap());
log.info("========================================");
}
}