Eureka 和 Feign 是 Spring Cloud 微服务架构中协同工作的两个核心组件,它们的关系可以通过以下比喻和详解来说明:
关系核心:服务发现 → 动态调用
组件 | 角色 | 核心功能 |
---|---|---|
Eureka | 服务注册中心 | 服务实例的"电话簿" |
Feign | 声明式HTTP客户端 | 根据"电话簿"智能拨号的"电话" |
协同工作流程
具体步骤:
服务注册(Eureka 核心功能)
服务提供者(如用户服务)启动时向 Eureka 注册自己的地址:# 用户服务的配置 eureka: client: service-url: defaultZone: http://eureka-server:8761/eureka
服务发现(Eureka 核心功能)
服务消费者(如订单服务)从 Eureka 获取可用服务列表:// 订单服务通过 Eureka 发现用户服务 List<ServiceInstance> instances = discoveryClient.getInstances("USER-SERVICE");
声明式调用(Feign 核心功能)
订单服务通过 Feign 声明调用接口(无需关注具体地址):@FeignClient(name = "USER-SERVICE") // 自动从Eureka查找服务 public interface UserClient { @GetMapping("/users/{id}") User getUser(@PathVariable Long id); }
动态路由 & 负载均衡(Feign + Ribbon)
Feign 底层集成 Ribbon 实现:- 从 Eureka 获取 USER-SERVICE 的所有实例
- 自动进行负载均衡(如轮询、随机等)
- 向选中的实例发送 HTTP 请求
关键协作点
1. 服务名称映射
@FeignClient(name = "USER-SERVICE")
// ^^^^^^^^^^^^^^^^^^^^^^
// 这个名称必须匹配Eureka中的注册名
2. 心跳维持连接
- Eureka 监控服务提供者状态(30秒心跳)
- Feign 实时获取健康实例列表,自动剔除故障节点
3. 故障转移
当 USER-SERVICE 某个实例宕机时:
- Eureka 检测到心跳停止 → 从注册表移除
- Feign 下一次调用自动切换到健康实例
典型架构场景
代码体现关系
订单服务中同时使用两者:
@SpringBootApplication
@EnableFeignClients // 启用Feign
@EnableEurekaClient // 注册到Eureka(同时也作为消费者)
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
// Feign客户端(自动从Eureka发现服务)
@FeignClient(name = "USER-SERVICE")
interface UserServiceClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id);
}
脱离 Eureka 的情况
虽然通常配合使用,但 Feign 也可独立工作:
- 直连模式(不推荐):
@FeignClient(name = "user", url = "http://localhost:8080")
- 使用其他注册中心(如 Nacos、Consul):
@FeignClient(name = "user-service") // 从Nacos获取实例
但 Eureka + Feign 是 Spring Cloud Netflix 的黄金组合,共同实现:
- 动态服务发现
- 负载均衡
- 声明式 HTTP 调用
- 故障自动转移