← 返回首页

Java服务发现机制详解

📂 java ⏱ 2 min 363 words

Java服务发现机制详解

什么是服务发现

服务发现是微服务架构中的核心组件,负责服务的注册、发现和健康检查,使服务之间能够动态通信。

Nacos服务发现

依赖配置

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置

spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: dev
        group: DEFAULT_GROUP
        weight: 1
        metadata:
          version: 1.0
          env: dev

服务注册

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

服务发现

@Service
public class ServiceDiscoveryService {
    @Autowired
    private DiscoveryClient discoveryClient;

    public List<ServiceInstance> getServiceInstances(String serviceName) {
        return discoveryClient.getInstances(serviceName);
    }

    public ServiceInstance getHealthyInstance(String serviceName) {
        return discoveryClient.getInstances(serviceName).stream()
            .filter(ServiceInstance::isHealthy)
            .findFirst()
            .orElseThrow(() -> new RuntimeException("没有可用实例"));
    }
}

负载均衡

@Configuration
public class LoadBalancerConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@Service
public class OrderService {
    @Autowired
    private RestTemplate restTemplate;

    public User getUser(Long id) {
        // 使用服务名替代host:port
        return restTemplate.getForObject(
            "http://user-service/api/users/" + id, User.class);
    }
}

Eureka服务发现

依赖配置

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置

spring:
  application:
    name: user-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    fetch-registry: true
    registry-fetch-interval-seconds: 5
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 10
    lease-expiration-duration-in-seconds: 30

Eureka Server

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

健康检查

@Component
public class CustomHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        if (isServiceHealthy()) {
            return Health.up().withDetail("service", "运行正常").build();
        }
        return Health.down().withDetail("service", "服务异常").build();
    }

    private boolean isServiceHealthy() {
        // 检查数据库连接、缓存等
        return true;
    }
}

服务版本管理

// Nacos元数据实现版本管理
spring:
  cloud:
    nacos:
      discovery:
        metadata:
          version: v2.0
          region: east-china

// 根据版本路由
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

// Feign指定版本
@FeignClient(name = "user-service", configuration = FeignConfig.class)
public interface UserClient {
    @GetMapping("/api/users/{id}")
    User getUser(@PathVariable("id") Long id);
}

@Component
public class FeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("X-Version", "v2.0");
    }
}

多集群部署

# Nacos集群配置
spring:
  cloud:
    nacos:
      discovery:
        server-addr: nacos1:8848,nacos2:8848,nacos3:8848
        namespace: production
        group: DEFAULT_GROUP
        cluster-name: cluster-a

服务优雅下线

@Component
public class GracefulShutdown implements DisposableBean {
    @Autowired
    private DiscoveryClient discoveryClient;

    @Override
    public void destroy() {
        // 1. 标记服务为不可用
        // 2. 等待现有请求处理完成
        // 3. 注销服务实例
        System.out.println("服务优雅下线");
    }
}

// 监听应用关闭事件
@Component
public class ShutdownListener implements ApplicationListener<ContextClosedEvent> {
    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        System.out.println("开始优雅下线...");
        // 处理逻辑
    }
}

Nacos vs Eureka

特性 Nacos Eureka
CAP模型 AP + CP AP
配置中心 支持 不支持
健康检查 TCP/HTTP 客户端心跳
服务元数据 丰富 有限
社区活跃度 高(国内) 一般

总结

服务发现是微服务架构的基石。Nacos在国内使用广泛,同时提供服务发现和配置中心。Eureka是Netflix开源的经典方案,适合需要AP模型的场景。