SpringCloud 声明式服务调用 —— Feign 全面解析(入门 + 原理 + 优化)

一、什么是 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 源码深度解析》

相关推荐
Foreer黑爷2 小时前
Spring MVC原理与源码:从请求到响应的全流程解析
java·spring·mvc
fy121632 小时前
Spring Boot spring-boot-maven-plugin 参数配置详解
spring boot·后端·maven
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第3题:ArrayList和LinkedList有什么区别
java·开发语言·后端·面试·list
jzwugang2 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第4题:LinkedList是单向链表还是双向链表
java·开发语言·数据结构·后端·链表·面试·list
Victor3563 小时前
MongoDB(95)如何在MongoDB中使用加密存储引擎?
后端
Victor3563 小时前
MongoDB(96)如何使用MongoDB的高级聚合功能?
后端
IT利刃出鞘4 小时前
Spring工具类--ObjectUtils的使用
java·后端·spring
2601_949816684 小时前
Spring boot启动原理及相关组件
数据库·spring boot·后端