package com.erp.common.nacos; import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.nacos.api.naming.pojo.Instance; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; import java.util.Optional; /** * Nacos服务注册与发现工具类 * 提供服务元数据管理、健康检查、实例查询等高级功能 */ @Slf4j @Component @RequiredArgsConstructor public class NacosServiceUtil { private final DiscoveryClient discoveryClient; private final Optional registration; private final NacosServiceManager nacosServiceManager; // ============================================================== // 1. 服务注册状态检查 // ============================================================== /** * 检查当前服务是否已注册到Nacos */ public boolean isRegistered() { return registration.isPresent(); } /** * 获取当前服务实例ID */ public String getInstanceId() { return registration.map(r -> r.getInstanceId()).orElse("unknown"); } /** * 获取当前服务实例信息 */ public Map getMetadata() { return registration.map(Registration::getMetadata).orElse(Map.of()); } // ============================================================== // 2. 服务发现 // ============================================================== /** * 根据服务名获取所有健康实例 */ public List getHealthyInstances(String serviceName) { return discoveryClient.getInstances(serviceName).stream() .filter(this::isHealthyInstance) .toList(); } /** * 根据服务名获取所有实例(包括不健康的) */ public List getAllInstances(String serviceName) { return discoveryClient.getInstances(serviceName); } /** * 检查目标服务是否可用(至少有一个健康实例) */ public boolean isServiceAvailable(String serviceName) { return !getHealthyInstances(serviceName).isEmpty(); } private boolean isHealthyInstance(ServiceInstance instance) { if (instance instanceof Instance nacosInstance) { return nacosInstance.isHealthy(); } return true; // 非Nacos实例默认健康 } // ============================================================== // 3. 服务元数据管理 // ============================================================== /** * 更新当前服务实例元数据 * 注意:需要Nacos 2.x客户端支持 */ public void updateMetadata(Map metadata) { registration.ifPresent(r -> { log.info("更新服务元数据: service={}, metadata={}", r.getServiceId(), metadata); // 元数据通过配置文件更新后,Nacos客户端会自动同步 }); } /** * 获取指定服务的所有实例及其元数据 */ public void printServiceDetails(String serviceName) { List instances = getAllInstances(serviceName); log.info("服务 [{}] 实例信息 (共{}个):", serviceName, instances.size()); for (ServiceInstance instance : instances) { log.info(" - InstanceId: {}", instance.getInstanceId()); log.info(" Host: {}:{}", instance.getHost(), instance.getPort()); log.info(" Metadata: {}", instance.getMetadata()); log.info(" Scheme: {}", instance.getScheme()); } } // ============================================================== // 4. 健康检查相关 // ============================================================== /** * 发送自定义心跳(用于临时实例或特殊保活需求) */ public void sendHeartbeat(String serviceName, String ip, int port) { log.debug("发送心跳: service={}, ip={}, port={}", serviceName, ip, port); // Nacos客户端自动发送心跳,通常不需要手动调用 // 此方法用于理解心跳机制 } /** * 获取Nacos客户端版本 */ public String getNacosClientVersion() { return nacosServiceManager.getNacosClientProperties().getProperty("nacos.client.version", "unknown"); } }