OpenFeign
简介
OpenFeign是基于声明式的REST 客户端,用于简化服务间远程调用。(编程式REST客户端(RestTemplate))
通过接口+注解方式定义HTTP请求,自动实现服务调用
常用注解:
- 指定远程地址:@FeignClient
- 指定请求方式:@GetMapping、@PostMapping、@DeleteMapping …
- 指定携带数据:@RequestHeader、@RequestParam、@RequestBody …
- 指定返回结果:响应模型
总结:OpenFeign是一种替代RestTemplate的工具,专门用来实现不同微服务之间实现远程调用的服务API,相比RestTemplate功能更强大,操作更简洁

使用示例
-
引入依赖
<!-- Spring Cloud OpenFeign 核心依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> -
开启功能
在主启动类添加注解:
@EnableFeignClients // 启用 OpenFeign 客户端功能 @SpringBootApplication public class Application { ... } -
远程调用
-
定义Feign客户端接口: (客户端:发送请求,服务端:接收请求)
-
远程调用--业务API
@FeignClient(value = "product-service")//声明要调用的Feign客户端,名称是application.yml中配置的名称,底层会自动去注册中心负载均衡的发送请求 public interface ProductFeignClient {//使用feign实现的专门向product服务进行调用的接口 //mvc注解的两套逻辑 //1.标注在Controller上,是接收这一样的请求 //2.标注在FeignClient上,是发送这样的请求 @GetMapping("/product/{id}") public Product getProductById(@PathVariable("id") Long productId); } //接收请求的时候是把这个id放到productId //发送请求的时候是把productId放到id上 -
远程调用--第三方API

-
如何编写好OpenFeign声明式的远程调用接口
- 业务API:直接复制对方Controller签名即可
- 第三方API:根据接口文档确定请求如何发
注入使用:
@Autowired
private UserClient userClient;
public User getUser(Long id) {
return userClient.getUserById(id); // 直接调用远程接口
}
面试题: 客户端负载均衡与服务端负载均衡区别?
负载均衡发生在客户端就是客户端负载均衡。
负载均衡发生在服务端就是服务端负载均衡。
进阶配置
开启日志
配置日志级别(application.yml)
# 客户端
logging:
level:
com.atguigu.order.Feign: DEBUG # 指定客户端接口的日志级别,直接复制包名,这样其下的所有客户端就都会开启日志功能
配置日志策略(java Config)
@Configuration
//注意一定是feign包下的Logger
import feign.Logger;
//OrderConfig
@Configuration
public class OrderConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // FULL/BASIC/HEADERS/NONE
}
}
超时控制(避免服务宕机)
商品服务卡慢导致订单服务卡慢,导致。。。链式效应进而导致整个服务的卡慢,(服务雪崩)因此我们需要一个超时控制机制。

connectTimeout: 打电话嘟嘟嘟,没人接(电话没接通)
readTimeout: 喂喂喂,没人回(电话接通了)

# application.yml
spring:
cloud:
openfeign:
client:
config:
default:
logger-level: full
connect-timeout: 1000 # ms
read-timeout: 2000
product-service:
logger-level: full
connect-timeout: 3000
read-timeout: 5000
重试机制
远程调用超时失败后,还可以进行多次尝试,如果某次成功返回ok,如 果多次依然失败则结束调用,返回错误。(一次调用失败我不甘心,我想多试几次。)

配置方式一 配置文件方式
# application.yml
spring:
cloud:
openfeign:
client:
config:
default:
retryable: true # 启用重试
maxAttempts: 3 # 最大重试次数
配置方式二 编码方式
@Bean
Retryer retryer(){
return new Retryer.Default();
}
//spring会自动把retryer注入到容器,注入之后底层会默认这个配置(源码)
public Default() {
this(100L, TimeUnit.SECONDS.toMillis(1L), 5);//请求超时默认发5次,最多1s
}
Fallback 兜底返回
-
引入sentinel
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> -
开启熔断
feign: sentinel: enabled: true -
编写Fallback函数
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class) // feign客户端 public interface ProductFeignClient { //mvc注解的两套使用逻辑 //1、标注在Controller上,是接收这样的请求 //2、标注在FeignClient上,是发送这样的请求 @GetMapping("/product/{id}") Product getProductById(@PathVariable("id") Long id); }// Feign包下创建一个FallBack包(兜底回调) // FallBack包在创建ProductFeignClientFallback,并且继承ProductFeignClient(接口) @Component//只有把这个兜底回调放在容器中才能实现兜底回调 public class ProductFeignClientFallback implements ProductFeignClient { //这个函数不一定会回调,只有出现超时情况才会调用这个函数 public Product getProductById(Long id) { System.out.println("兜底回调...."); Product product = new Product(); product.setId(id); product.setPrice(new BigDecimal("0")); product.setProductName("未知商品"); product.setNum(0); return product; } }
拦截器用法

- 请求拦截器
- 响应拦截器(用的不多)
自定义拦截器
import feign.RequestInterceptor;
@Component//如果放入IOC容器就会自动注册拦截器,可以不做后面的注册
public class XTokenRequestInterceptor implements RequestInterceptor {
/**
*请求拦截器
*template 请求模板
*/
@Override
public void apply(RequestTemplate template) {
System.out.println("XTokenRequestInterceptor.......");
template.header("X-Token", "UUID.randomUUID.toString()"); // 添加请求头,用作身份验证
}
}
注册拦截器(配置类中):
@Configuration
public class FeignConfig {
@Bean
public AuthInterceptor authInterceptor() {
return new AuthInterceptor();
}
}
重点总结
| 核心内容 | 关键点 | 备注 |
|---|---|---|
| 远程调用客户端 | 通过 @FeignClient 定义接口,使用 @GetMapping 等注解声明 HTTP 方法。 |
|
| 超时控制 | 配置 connectTimeout 和 readTimeout,支持全局和按服务配置。 |
|
| 重试机制 | 启用 retryable 并设置 maxAttempts,增强服务调用容错性。 |
|
| Fallback 兜底 | 实现 Fallback 类处理服务降级,防止级联故障。 | |
| 拦截器 | 通过 RequestInterceptor 添加统一请求头或认证信息。 |
注意事项:
- 生产环境建议配置合理的超时时间和重试策略,避免雪崩效应。
- 拦截器可用于统一认证、日志跟踪等场景。
OpenFeign 与 Dubbo 的区别
Dubbo 和 OpenFeign 都是java生态中两个广泛使用的远程过程调用(RPC)框架,两者主要在稳定性、独立性和易用性等方面有所区别,具体如下:
- 稳定性
- Dubbo:基于TCP进行传输,处于更底层的模型,数据传输稳定,特别是处理大量并发请求时表现优秀
- OpenFeign:基于HTTP协议进行传输,通常为短连接,适合轻量级微服务调用,但在高并发场景下可能不如Dubbo稳定
- 独立性
- Dubbo:是一个独立的RPC框架,提供了完整的服务治理解决方案,不依赖其他系统或者框架
- OpenFeign:作为Spring Cloud 生态的一部分,与Spring Cloud 集成紧密,简化了服务间的调用,但相对依赖Spring生态系统
- 易用性
- Dubbo:需要较多的配置和代码实现,但能够提供灵活的服务治理能力
- OpenFeign:使用非常简单,只需要在接口上添加注解即可完成服务的暴露与调用,降低了学习成本和开发成本
- 负载均衡
- Dubbo:支持随机、轮询、活跃度、Hash一致性等多种算法,并引入权重概念,支持动态配置
- OpenFeign:支持轮询,随机,ResponseTime加权等策略,但相对较为简单
- 容错策略
- Dubbo:支持failover、failfast、broadcast、forking等多种容错策略,并可配置retry次数和timeout参数
- OpenFeign:利用熔断机制进行容错处理,与Dubbo的处理方式有所不同
- 适用场景
- Dubbo:适用于大型的分布式项目,能够处理复杂的业务逻辑和高并发请求
- OpenFeign:适合轻量级的微服务架构,业务逻辑相对简单,并且与Spring Cloud技术栈配合使用更佳
综合对比分析,Dubbo更适合大规模、高并发的分布式系统,其强大的服务治理能力和灵活性使其在复杂场景下表现突出。相反,OpenFeign更加适合轻量级微服务架构,其简洁性和与Spring Cloud的集成度使得开发和部署更加便捷。此外,技术栈的熟悉程度和团队经验也是选择的重要考虑因素。
在选择时,提供如下几点建议:
- 如果当前项目已经基于Spring Cloud构建,推荐使用OpenFeign以减少整合成本。
- 对于对性能有极高要求或者独立的RPC框架需求的项目,Dubbo将是更好的选择。
- 考虑到社区活跃度和支持,Dubbo可能提供更多的文档和问题解决途径。
- 如果计划构建一个全新项目,可以依据具体的业务需求、团队技能和未来的拓展预期来决定使用哪个框架。
综上所述,Dubbo和OpenFeign各有优势,选择合适的框架取决于具体的项目需求和应用场景。在做出决策之前,请仔细评估项目的规模、技术栈和性能要求。无论选择哪个框架,都需要深入理解其工作原理和最佳实践,以便在实际应用中获得最佳的性能和可靠性。


浙公网安备 33010602011771号