在 Spring Cloud 微服务架构中,OpenFeign 是一种声明式的 HTTP 客户端,它允许开发者像调用本地方法一样发起远程服务请求。
以下是一个完整的示例,包含**被调用端(服务提供者 user-service)和 调用端(服务消费者 order-service)**的核心代码及配置。
一、 被调用端:用户服务 (user-service)
这是提供基础接口的服务。
1. 配置文件 (application.yml)
yaml
server:
port: 8081
spring:
application:
name: user-service # 注册到注册中心的服务名
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 假设使用 Nacos 作为注册中心
2. 启动类 (UserApplication.java)
java
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
3. 实体类与接口 (UserController.java)
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
private Long id;
private String name;
}
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public UserDTO getUserById(@PathVariable Long id) {
// 模拟数据库查询
return new UserDTO(id, "张三-" + id);
}
}
二、 调用端:订单服务 (order-service)
这是通过 Feign 调用 user-service 的服务。
1. 引入核心依赖 (pom.xml)
需要引入 OpenFeign 以及服务发现的依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2. 配置文件 (application.yml)
建议配置超时时间,避免高延迟场景下服务卡死:
yaml
server:
port: 8082
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
# Feign 超时配置
feign:
client:
config:
default:
connectTimeout: 5000 # 连接超时时长(毫秒)
readTimeout: 5000 # 读取超时时长(毫秒)
3. 启动类 (OrderApplication.java)
关键步骤: 必须添加 @EnableFeignClients 注解来开启 Feign 客户端扫描。
java
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 开启OpenFeign客户端扫描
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
4. 定义 Feign 客户端接口 (UserFeignClient.java)
通过 @FeignClient 绑定远程服务,方法签名与被调用端的 Controller 保持一致:
java
@FeignClient(name = "user-service") // name 为被调用方在注册中心的服务名
public interface UserFeignClient {
@GetMapping("/users/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
}
5. 业务调用 (OrderService.java)
直接注入 Feign 接口,像调用本地方法一样完成远程通信:
java
@Service
public class OrderService {
@Autowired
private UserFeignClient userFeignClient;
public String createOrder(Long userId) {
// 底层会自动发起 HTTP GET 请求到 user-service
UserDTO user = userFeignClient.getUserById(userId);
return "订单创建成功!关联用户信息:" + user.getName();
}
}
💡 开发避坑提示:
- 参数注解不能省 :Feign 接口方法的参数上必须显式加上
@PathVariable、@RequestParam或@RequestBody等注解,否则可能导致参数传递失败。 - GET 请求限制 :Feign 的 GET 请求不支持使用
@RequestBody传递复杂对象参数,如需传递对象请使用 POST 请求或使用@SpringQueryMap注解。 - 生产环境建议 :在实际项目中,强烈建议在
@FeignClient中配置fallback或fallbackFactory属性,结合 Sentinel 或 Hystrix 实现熔断降级,防止单个服务故障导致整个系统雪崩。