Java服务发现机制详解
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模型的场景。