138 lines
4.6 KiB
Java
138 lines
4.6 KiB
Java
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> 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<String, String> getMetadata() {
|
||
return registration.map(Registration::getMetadata).orElse(Map.of());
|
||
}
|
||
|
||
// ==============================================================
|
||
// 2. 服务发现
|
||
// ==============================================================
|
||
|
||
/**
|
||
* 根据服务名获取所有健康实例
|
||
*/
|
||
public List<ServiceInstance> getHealthyInstances(String serviceName) {
|
||
return discoveryClient.getInstances(serviceName).stream()
|
||
.filter(this::isHealthyInstance)
|
||
.toList();
|
||
}
|
||
|
||
/**
|
||
* 根据服务名获取所有实例(包括不健康的)
|
||
*/
|
||
public List<ServiceInstance> 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<String, String> metadata) {
|
||
registration.ifPresent(r -> {
|
||
log.info("更新服务元数据: service={}, metadata={}", r.getServiceId(), metadata);
|
||
// 元数据通过配置文件更新后,Nacos客户端会自动同步
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取指定服务的所有实例及其元数据
|
||
*/
|
||
public void printServiceDetails(String serviceName) {
|
||
List<ServiceInstance> 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");
|
||
}
|
||
}
|