一、什么是 Feign?
Feign 是 Spring Cloud 提供的一种 声明式 HTTP 客户端,主要特点如下:
-
✅ 工作在 Consumer(消费方)
-
✅ 通过 接口 + 注解 的方式定义服务调用
-
✅ 支持 Spring MVC 注解(
@RequestMapping、@GetMapping等) -
✅ 内置 Ribbon,天然支持客户端负载均衡
👉 一句话总结:
Feign = RestTemplate + Ribbon + 接口代理
二、Feign 快速入门案例
1️⃣ 服务提供方(feign-provider)
-
提供 REST 接口
-
注册到注册中心(如 Eureka / Nacos)
示例接口:
@RestController
@RequestMapping("/provider")
public class UserController {
@GetMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id) {
return new User(id, "张三");
}
}
2️⃣ Feign 接口模块(feign-interface)
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Feign 接口定义
@FeignClient("feign-provider")
@RequestMapping("/provider")
public interface UserFeign {
@GetMapping("/getUserById/{id}")
User getUserById(@PathVariable("id") Integer id);
}
✅ 要点说明:
-
@FeignClient("feign-provider"):指定调用的服务名 -
接口方法写法 ≈ Controller 接口写法
3️⃣ 服务消费方(feign-consumer)
pom.xml
<dependency>
<groupId>com.hg</groupId>
<artifactId>feign-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Controller 调用
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private UserFeign userFeign;
@GetMapping("/getUser/{id}")
public User getUser(@PathVariable Integer id) {
return userFeign.getUserById(id);
}
}
启动类
@SpringBootApplication
@EnableFeignClients
public class FeignConsumerApp {
public static void main(String[] args) {
SpringApplication.run(FeignConsumerApp.class, args);
}
}
三、Feign 工作原理(核心)
1️⃣ 扫描并注册 Feign Client
-
@EnableFeignClients开启 Feign 支持 -
FeignClientsRegistrar.registerFeignClients()👉 扫描
@FeignClient标识的接口 -
为每个接口生成 JDK 动态代理对象
-
代理对象交由 Spring 容器管理
2️⃣ 方法调用时创建 RequestTemplate
-
Consumer 调用 Feign 接口方法
-
代理类调用
SynchronousMethodHandler.invoke() -
根据方法注解生成
RequestTemplate -
最终交给 Http Client 执行请求
📌 整体流程:
Controller
↓
Feign 接口(代理)
↓
RequestTemplate
↓
Ribbon 负载均衡
↓
HTTP 请求
四、Feign 常见传参方式
| 传参方式 | 注解 | 示例 |
|---|---|---|
| ?参数 | @RequestParam |
/user?id=1 |
| Restful | @PathVariable |
/user/1 |
| JSON | @RequestBody |
{ "id":1 } |
示例:
@GetMapping("/getUser")
User getUser(@RequestParam("id") Integer id);
@PostMapping("/saveUser")
String saveUser(@RequestBody User user);
五、Feign 性能优化(重点)
✅ 1️⃣ 开启 Feign 日志
feign:
client:
config:
feign-provider:
loggerLevel: full
logging:
level:
com.hg.feign: debug
📌 日志级别:
-
NONE(默认) -
BASIC -
HEADERS -
FULL
✅ 2️⃣ 使用 HTTP 连接池(推荐)
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
✅ 避免频繁创建连接,提高性能
✅ 3️⃣ 开启 GZIP 压缩
server:
compression:
enabled: true
feign:
compression:
request:
enabled: true
response:
enabled: true
✅ 4️⃣ 超时配置(非常重要)
方式一:Ribbon
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
方式二:Feign
feign:
client:
config:
feign-provider:
connectTimeout: 5000
readTimeout: 5000
✅ 5️⃣ 自定义负载均衡策略
@Configuration
public class IRuleConfig {
@Bean
public IRule iRule() {
return new WeightedResponseTimeRule(); // 权重
}
}
六、总结
✅ Feign 是 声明式、简化微服务调用的神器
✅ 底层集成 Ribbon,支持负载均衡
✅ 通过接口 + 注解即可完成服务调用
✅ 实际项目中建议开启 日志、连接池、压缩、超时配置
📌 适合人群:Spring Cloud 初学者 / 微服务入门
📌 推荐搭配:Eureka + Feign + Ribbon
如果你愿意,我也可以帮你再补一篇:
👉《Feign vs RestTemplate 实战对比》或《Feign 源码深度解析》