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 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 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("========================================"); } }