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 源码深度解析》

相关推荐
UrbanJazzerati11 小时前
AutoHotkey v2 零基础快速入门 Part 10:给路线回放添加高精度计时,理解累计延迟与路线一致性
后端
70后写java的老码农11 小时前
Spring Boot 3 + ShardingSphere-JDBC 实战:一次把读写分离和分库分表跑通
后端
泡海椒11 小时前
04-饼图评级构成-信用评级构成
后端
知守观11 小时前
多模块架构演进:横向分层 vs 纵向领域,13 个真实项目的切分对照
java·后端·微服务
系统集成-鹰翔12 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
软件技术NINI14 小时前
基于SpringBoot和Vue的摇滚乐鉴赏网站
vue.js·spring boot·后端·spring·html·毕业设计·毕设
Tsuki_tl14 小时前
【总结】Redis五大数据类型应用场景及基本命令
数据库·redis·后端·缓存·缓存中间件·redis命令·redis 五大数据类型
后台模板学习14 小时前
Go Web开发中任务调度框架的源码解析与高可用实现方案
开发语言·后端·golang
系统集成-鹰翔14 小时前
ERP对接升级提示数据库迁移失败:SQLite逐版本事务到底回滚到哪一步
javascript·数据库·经验分享·后端
IT_陈寒14 小时前
深入理解SpringBoot:核心原理与最佳实践
前端·人工智能·后端