124 lines
4.5 KiB
Java
124 lines
4.5 KiB
Java
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("========================================");
|
||
}
|
||
}
|