约定
本系列feign的版本使用的是13.3
feign的前世今生
起源和诞生
Feign 最初是由 Netflix 开发并开源的,作为其微服务架构中实现服务调用的重要组成部分。Netflix 在构建其微服务生态系统(如 Eureka、Hystrix、Zuul)时,需要一种方便的方式来让微服务之间进行 HTTP 通信。Feign 的设计目的是简化 REST 客户端的开发,通过声明式接口来自动生成 HTTP 客户端实现。
设计特点
-
声明式 HTTP 客户端:Feign 允许开发者定义接口,并使用注解来配置每个方法对应的 HTTP 请求。开发者无需手动编写大量的 HTTP 请求代码。
-
与 Spring Cloud 集成:随着 Feign 被越来越多的开发者采用,Spring Cloud 团队也将其集成到 Spring Cloud Netflix 项目中,使得开发者可以结合 Spring Cloud 的其他组件(如 Eureka 和 Ribbon)实现服务发现和负载均衡
发展演变
- 初期版本(Netflix OSS):
Feign 最初与 Netflix OSS 一起推出,提供了基于注解的简洁方式来定义 HTTP 客户端接口。它与 Ribbon 和 Hystrix 集成,提供了负载均衡和容错功能。
-
Spring Cloud Feign:
Spring Cloud 团队基于 Netflix Feign 扩展了其功能,允许开发者使用 Spring 注解和 @FeignClient 来更好地集成到 Spring 应用中。开发者可以通过配置文件来调整客户端的行为,如超时设置和重试策略。
-
OpenFeign:
随着 Netflix OSS 宣布一些组件进入维护模式,OpenFeign 逐渐取代了原来的 Netflix Feign。OpenFeign 是 Feign 的开源社区版本,继续维护和更新核心功能。Spring Cloud 也将其 @FeignClient 注解转向与 OpenFeign 集成,使得 Feign 在现代 Spring 应用中依然广泛使用。
使用场景与现代应用
- 服务间通信:定义 REST 客户端以便调用其他微服务的 API。
- 负载均衡:结合 Ribbon 和 Spring Cloud LoadBalancer,实现负载均衡请求。
- 集成:与 Spring Boot 和 Spring Cloud 无缝集成,使用 @FeignClient 注解来定义服务客户端。
java版本兼容
Feign 10.x 及以上版本基于 Java 8,应该可以在 Java 9、10 和 11 上正常运行。如果需要与 JDK 6 兼容,请使用 Feign 9.x 版本。
未来
看一段springcloud官网的声明
由于 Spring 现在提供了自己的接口 HTTP 客户端解决方案,从 2022.0.0 开始,我们将 Spring Cloud OpenFeign 视为功能完整。这意味着 Spring Cloud 团队将不再向模块添加新功能。我们仍将修复错误和安全问题,我们还将考虑和审查来自社区的小型拉取请求。
springcloud将不再新增模块, 只会做一些维护, 但是有一个不争的事实是目前存量项目以及未来一段时间, feign依然是我们项目中使用的主流, 技术的更新换代很快, 但是市场反应的滞后时间也很长, 所以和我们去了解一个http客户端框架并不冲突, 并且openfeign作为当下流行且轻巧的框架, 学习它用来将来举一反三也有很大的意义。
feign的项目地址
模块图
1. clients: 同步客户端
提供同步远程调用的支持, 包括java原生的HttpURLConnection(hc)、okhttp、Apache HttpClient等
2. async clients: 异步客户端
async clients 模块允许 Feign 客户端以异步方式执行 HTTP 请求,返回 CompletableFuture 或其他异步类型,而不是同步地等待响应。这样,调用方可以在等待响应时执行其他任务,提高系统资源利用率。
特点:
• 异步执行:支持非阻塞的 HTTP 请求,利用现代 Java 并发 API,如 CompletableFuture。
• 响应处理:异步调用允许处理长时间操作,例如远程调用、网络请求和 I/O 操作。
• 线程资源优化:减少阻塞线程数,使应用程序能够同时处理更多请求。
3. contracts: 协议的一些约定
Feign 的 contracts 模块是 Feign 框架中一个核心部分,它定义了如何将 Java 接口解析成 HTTP 请求。Contract 是 Feign 用来解析接口的策略模式接口,它将接口方法上的注解转换为 Feign 可理解的请求模板,从而生成适合的 HTTP 请求。
Contract 模块主要负责:
• 解析接口上的注解和方法签名。
• 将接口方法映射为 Feign 的请求信息,包括请求路径、方法、参数等。
• 使 Feign 支持自定义的注解处理,开发者可以根据需求扩展或修改默认行为。
默认约定支持的url模版遵循URI 模板 - RFC 6570 规范;
==默认支持的注解如下==
| 注解 | 目标接口 | 用法 |
|---|---|---|
@RequestLine | Method方法 | 定义请求的 HttpMethod 和 UriTemplate。 Expressions,括在大括号 {expression} 中的值使用其相应的@Param注释参数进行解析。 |
@Param | Parameter参数 | 定义一个模板变量,其值将用于解析相应的模板 Expression,按作为注释值提供的名称。如果缺少 value,如果未提供注解值,它将尝试从方法参数的字节码名称中获取(前提是代码在编译时使用了 -parameters 标志)。 |
@Headers | Method, Type方法、类型 | 定义 HeaderTemplate;UriTemplate 的变体。 ,它使用@Param带注释的值来解析相应的 Expressions。 在 Type 上使用时,模板将应用于每个请求。 在 Method 上使用时,模板将仅应用于带注释的方法。 |
@QueryMap | Parameter参数 | 定义 Map 或 POJO,以扩展为查询字符串。 |
@HeaderMap | Parameter参数 | 定义 Map,以扩展到 Http Headers |
@Body | Method方法 | 定义一个 Template,类似于 UriTemplate 和 HeaderTemplate,它使用@Param带注释的值来解析相应的Expressions。 |
4. encoders/decoders
在 Feign 中,encoders 和 decoders 模块用于将请求和响应数据进行编码和解码。它们是 Feign 框架实现序列化和反序列化的核心组件,帮助开发者将 Java 对象与 HTTP 请求和响应进行数据转换。
encoders(编码器)
• 作用:将 Java 对象序列化为 HTTP 请求体。例如,在发送 JSON 数据时,将 Java 对象转换为 JSON 格式。
• 内置实现:Feign 提供了基础的 Encoder 实现,可以支持简单的表单数据、URL 编码等。使用第三方库如 Jackson 或 Gson 可以支持 JSON 格式。
decoder(解码器) • 作用:将 HTTP 响应数据反序列化为 Java 对象。例如,解析 JSON 响应并将其映射到 Java 类。 • 内置实现:Feign 提供了基础的 Decoder 实现,可以解析简单的字符串和数据。为了支持更复杂的格式(如 JSON),需要集成 Jackson、Gson 等库。
5. metrics
Feign 的 metrics 模块提供了对请求的各种度量,如请求的成功率、失败率、延迟时间等。这些信息可以用于:
• 监控请求的健康状况和性能。
• 提高服务质量和系统可靠性。
• 进行性能调优和故障排查。
6.extras
extras 模块包含额外的支持功能,扩展了 Feign 的基本能力,通常用于整合与第三方库、功能模块或增强现有特性的集成。这部分模块并不一定在核心 Feign 包中,而是作为附加功能提供给用户以满足更复杂的需求。例如提供负载均衡, 断路器等。
feign的基本功能组件图

其中比较核心的地方用颜色做了填充
feign的请求流程图
借一张图

Netflix Feign还是Open Feign?
首先需要明确: 他两属于同一个东西, Feign属于Netflix开源的组件。针对差异, 下面分别给出对比
1、GAV坐标差异
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
</dependency>
2、官网地址
https://github.com/Netflix/feign 和 https://github.com/OpenFeign/feign。不过现在访问https://github.com/Netflix/feign已经被重定向到后者上了。
3、发版历史
- Netflix Feign:
1.0.0发布于2013.6, 于2016.7月发布其最后一个版本8.18.0 - Open Feign: 首个版本便是
9.0.0,于2016.7月发布,然后一直持续发布到现在(未停止)
从以上3个特点其实你可以很清楚的看到两者的区别和联系,简单的理解: Netflix Feign 仅仅只是改名成为了 open Feign 而已,然后Open Feign项目在其基础上继续发展至今
Spring-cloud-starter-feign还是spring-cloud-starter-openfeign?
他俩的差异类似于上述描述的差异,也从几个方面说明
1、GAV坐标差异
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、发展历史
- spring-cloud-starter-feign: 2015.3发布1.0.0版本,2019.5.23发布其最后一个版本 1.4.7.RELEASE
- 值得注意的是,从 1.4.0.RELEASE 开始,它的1.4.x的发版轨迹完全同下的1.4.x的发版轨迹
- spring-cloud-starter-openfeign: 2017.11发布其首个版本,版本号为: 1.4.0,RELEASE。现在仍持续更新中,当下最新版为 2.2,1.RELEASE
[!NOTE]
说明: 1.4.7.RELEASE是整个Spring Cloud1.x关于Feign方面的最终版本,2.x版本还在持续维护更新中
注意: 老的sprine-dloud-starter-openFeign从 1.2.0.RELEASE 开始已放弃Netflix feign而全面使用更新的Open Feign版本,而soring-coud-starter-openFeign更是和Netflix Feign已经没有关系了
对于版本,可粗略的理解为: spring-cloud-starter-openFeign 是为Spring Cloud2x准备的,只不过维持了一段时间的对1x的兼容。而spring-cloud-starter-feign 是专为Spring Cloud1.x服务。