微服务学习-服务调用组件 OpenFeign 实战
1. OpenFeign 接口方法编写规范
1.1. 在编写 OpenFeign 接口方法时,需要遵循以下规范
1.1.1.1. 接口中的方法必须使用 @RequestMapping、@GetMapping、@PostMapping 等注解声明 HTTP 请求的类型。
1.1.1.2. 方法的参数可以使用 @RequestParam、@RequestHeader、@PathVariable 等注解来制定如何传递 HTTP 请求的参数。
1.1.1.3. 可以使用 @RequestBody 来指定如何传递请求体中的参数。
1.1.1.4. 可以使用 @HearderMap 来传递头部信息。
1.2. 案例演示
1.2.1.1. Get 请求
get 请求,参数全放 URL 中,不建议放 Body,部分浏览器可能会限制不能读取 body 中的数据;
get 请求参数过长的话,也会有问题,适用于参数不长的场景。
目标接口方法:
@GetMapping("/getOrderByUserId")
public Result<List<OrderResponse>> getOrderByUserId(@RequestParam("userId") Long userId)
OpenFeign 接口方法
@GetMapping("/getOrderByUserId")
Result<List<OrderResponse>> getOrderByUserId(@RequestParam("userId") Long userId);
1.2.1.2. post 请求
1.2.1.2.1. @RequestBody
目标接口方法:
@RequestMapping(value = "/post1")
public Result<OrderResponse> post1(@RequestBody OrderRequest orderRequest)
OpenFeign 接口方法
@PostMapping("/post1")
Result<OrderResponse> post1(@RequestBody OrderRequest orderRequest);
1.2.1.2.2. URL 后面追加参数
除了放在 body 中的参数,还能直接 url 后面追加参数,@RequestParam 注解
例如:增加参数 token http:/XXXXXXXX?token=xxxxxx
目标接口方法:
@RequestMapping(value = "/post2")
public Result<OrderResponse> post2(@RequestBody OrderRequest orderRequest, @RequestParam("token") String token)
OpenFeign 接口方法:
@PostMapping("/post2")
Result<OrderResponse> post2(@RequestBody OrderRequest orderRequest, @RequestParam("token") String token);
1.2.1.2.3. url 中加参数
url 中追加参数,参数用 @PathVariable 注解
目标接口方法:
@RequestMapping(value = "/post3/{userId}")
public Result<OrderResponse> post3(@RequestBody OrderRequest orderRequest, @PathVariable("userId") Long userId)
OpenFeign 接口方法:
@PostMapping("/post3/{userId}")
Result<OrderResponse> post3(@RequestBody OrderRequest orderRequest, @PathVariable("userId") Long userId);
2. OpenFeign 的调用流程

3. OpenFeign 常用扩展点配置
openFeign 提供了很多的扩展机制,让用户可以更加灵活的使用。
3.1. 测试环境
速通版:git checkout v2.0.0 版本:
icoolkj-microservices-code 标签 - Gitee.com
会员服务调用订单服务。

3.2. 日志配置
配置 Feign 的日志,让 Feign 把请求信息输出,方便查找问题等。
日志级别有4 种:
- NONE【性能最佳,默认值】:不记录任何日志。
- BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
- FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
3.2.1.1. 配置方式
3.2.1.1.1. Java Bean 方式
全局生效:利用 @Configuration 实现全局生效,对所有的微服务调用者都生效。
-
- 定义一个配置类,指定日志级别
// 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置@Configuration
@Configuration
public class FeignConfig {/*** 日志级别* @return*/@Beanpublic Logger.Level feignLoggerLevel(){return Logger.Level.FULL;}}
-
- 在 application.yml 中配置 Client 的日志级别才能正常输出日志
格式:logging.level.feign 接口包路径=debug
logging:level:com.icoolkj.mall.user.openfeign.demo.feign: debug
-
- 重启测试
分别选择日志级别进行测试,查看控制台输出结果信息。
局部生效:让指定的微服务生效,在 @FeignClient 注解中指定 configuration
@FeignClient(name = "icoolkj-mall-order01", path = "/api/order", configuration = OpenFeignConfig.class)
public interface OrderFeignService {
注意:此时配置类不能添加 @Configuration 注解 。
3.2.1.1.2. yum 配置文件方式
全局生效:配置{服务名} 为 default,对应的微服务调用者都生效。
spring:cloud:openfeign:client:config:default:loggerLevel: FULL
局部生效:配置{服务名}为具体的服务名(icoolkj-mall-order01),对调用的微服务提供者生效。
spring:cloud:openfeign:client:config:icoolkj-mall-order01:loggerLevel: FULL
3.2.1.1.3. 配置方式选择
建议使用 yml 配置,可以利用配置中心对配置进行统一管理。
3.3. 超时时间配置
3.3.1.1. OpenFeign 使用两个超时参数
connectionTimeout 可以防止由于较长的服务器处理时间而阻塞调用者。
readTimeout 从连接建立时开始应用,当返回响应花费太长时间时触发。
注意:OpenFeign 底层使用 LoadBalancer,但是超时以 OpenFeign 配置为准。
3.3.1.2. 配置方式
3.3.1.2.1. Java bean 方式
通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时时间(ms);第二个是请求处理的超时时间(ms)。
@Bean
public Request.Options options() {return new Request.Options(3000, 5000);
}
3.3.1.2.2. yml 配置文件方式
spring:cloud:openfeign:client:config:icoolkj-mall-order01:loggerLevel: FULL# 连接超时时间connectTimeout: 3000# 请求处理超时时间readTimeout: 5000
3.3.1.2.3. 测试配置是否生效
利用 Thread.sleep 来修改订单接口调用时间,验证是否超时。
3.4. 契约配置
Spring Cloud 在 Feign 的基础上做了扩展,可以让 Feign 支持 Spring MVC 的注解来调用。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。
3.4.1.1. 配置方式
3.4.1.1.1. Java Bean 方式
@Bean
public Contract feignContract(){return new Contract.Default();
}
3.4.1.1.2. yml 配置文件方式
spring:cloud:openfeign:client:config:icoolkj-mall-order01:loggerLevel: FULL# 连接超时时间connectTimeout: 3000# 请求处理超时时间readTimeout: 5000# 指定contract: feign.Contract.Default
注意:修改契约配置后,OrderFeignService 不在支持 SpringMvc 的注解,需要使用 Feign 原生的注解。
Class OrderFeignService has annotations [FeignClient] that are not used by contract Default
@FeignClient(name = "icoolkj-mall-order01", path = "/api/order")
public interface OrderFeignService {// 使用 Feign 原生注解调用@RequestLine("GET /getOrderByUserId?userId={userId}")Result<List<OrderResponse>> getOrderByUserId(@Param("userId") Long userId);
}
3.5. 客户端组件配置
Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,没有连接池,我们可以集成别的组件来替换掉 URLConnection,比如 Apache HttpClient5,OKHttp。
Feign 发起调用真正执行逻辑:feign.Client#execute(扩展点)

3.5.1.1. 配置 Apache HttpClient5(推荐)
3.5.1.1.1. 引入依赖
<!-- Apache HttpClient5 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-hc5</artifactId>
</dependency>
3.5.1.1.2. 修改 yml 配置,启用 Apache HttpClient5,引入依赖后默认启用的,可以忽略
spring:cloud:openfeign:httpclient:hc5:enabled: true
关于配置可参考:org.springframework.cloud.openfeign.FeignAutoConfiguration

3.5.1.1.3. 重启测试
调用会进入 feign.hc5.ApacheHttp5Client#execute

3.5.1.2. 配置 OkHttp
3.5.1.2.1. 引入依赖
<!-- okhttp -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>
3.5.1.2.2. 修改 yml 配置,将 Feign 的 HttpClient 禁用,启用 OkHttp。
spring:cloud:openfeign:httpclient:hc5:enabled: falseokhttp:enabled: true
关于配置可参考:org.springframework.cloud.openfeign.FeignAutoConfiguration

3.5.1.2.3. 重启测试
调用会进入 feign.okhttp.OkHttpClient#execute

3.6. GZIP 压缩配置
开启压缩可以有效节约网络资源,提升接口性能,我们可以配置 GZIP 来压缩数据
spring:openfeign:compression: # 配置 GZIP 来压缩数据request:enabled: truemime-types: text/xml,application/xml,application/jsonmin-request-size: 1024 # 最小请求压缩阈值response:enabled: true
关于配置可参考:
org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoConfiguration
3.7. 编码器解码器配置
Feign 中提供了自定义的编码器解码器设置,同时也提供了多种编码器的实现,比如 Gson、Jaxb、Jackson。我们可以用不同的编码器解码器来处理数据的传输。如果你想传输 XML 格式的数据,可以自定义 XML 编码器解码器来实现,或者使用官方提供的 Jaxb。
扩展点:feign.codec.Encoder & feign.codec.Decoder
public interface Encoder {void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
}public interface Decoder {Object decode(Response var1, Type var2) throws IOException, DecodeException, FeignException;
}
3.8. 配置方式
3.8.1.1.1. 引入依赖
<!-- jackson -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-jackson</artifactId>
</dependency>
3.8.1.1.2. Java Bean 方式
@Bean
public Encoder encoder(){return new JacksonEncoder();
}@Bean
public Decoder decoder(){return new JacksonDecoder();
}
3.8.1.1.3. yml 配置文件方式
spring:cloud:openfeign:client:config:icoolkj-mall-order01:# 配置编码器解码器encoder: feign.jackson.JacksonEncoderdecoder: feign.jackson.JacksonDecoder
3.9. 拦截器配置
通过拦截器实现参数传递。
常用场景:统一添加 header 信息,比如向服务提供者传递全局事务 XID,会员 ID,认证 token 令牌,链路追踪的 traceID 等等。
扩展点:feign.RequestInterceptor
public interface RequestInterceptor {void apply(RequestTemplate var1);
}
每次 feign 发起 http 调用之前,会去执行拦截器中的逻辑。
3.9.1. 自定义拦截器实现认证逻辑
需求场景,微服务调用链路需要传递请求头的 token 信息

如果不做任何配置,直接使用 openFeign 在服务间进行调用就会丢失请求头。
解决方案:
3.9.1.1. 方案1:增加接口参数
@RequestMapping(value = "/api/product/getPriceProduct", method = RequestMethod.GET)
String getPriceProduct(@RequestParam(value = "productId") Long productId, @RequestHeader(value = "token") String token);
该方案不好,代码有侵入性,需要开发人员每次手动获取和添加接口参数。
3.9.1.2. 方案2:添加拦截器
OpenFeign 在远程调用之前会遍历容器中的 RequestInterceptor,调用 RequestInterceptor 的 apply 方法,创建一个新的 Request 进行远程服务调用。因此可以通过实现 RequestInterceptor 给容器中添加自定义的 RequestInterceptor 实现类,这个类里面设置需要发送请求的参数,比如请求头信息,链路追踪信息等。

3.9.1.2.1. 代码实现拦截器:
@Slf4j
public class FeignAuthRequestInterceptor implements RequestInterceptor{@Overridepublic void apply(RequestTemplate template) {// 业务逻辑,模拟认证逻辑ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(null != requestAttributes){HttpServletRequest request = requestAttributes.getRequest();String access_token = request.getHeader("Authorization");log.info("从 Request 中解析请求头:{}", access_token);// 设置 tokentemplate.header("Authorization", access_token);}}
}
3.9.1.2.2. 配置拦截器生效
方式1,Java Bean
@Bean
public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){return new FeignAuthRequestInterceptor();
}
方式2,yml 配置文件
spring:cloud:openfeign:client:config:icoolkj-mall-order01: #对应微服务request-interceptors: # 配置拦截器- com.icoolkj.mall.user.openfeign.demo.interceptor.FeignAuthRequestInterceptor
3.9.1.2.3. 重启测试
postman 中增加请求头参数 Authorization,查看会员服务 openFeign 日志是否有 Authorization 信息。

相关文章:
微服务学习-服务调用组件 OpenFeign 实战
1. OpenFeign 接口方法编写规范 1.1. 在编写 OpenFeign 接口方法时,需要遵循以下规范 1.1.1.1. 接口中的方法必须使用 RequestMapping、GetMapping、PostMapping 等注解声明 HTTP 请求的类型。 1.1.1.2. 方法的参数可以使用 RequestParam、RequestHeader、PathVa…...
关于安卓greendao打包时报错问题修复
背景 项目在使用greendao的时候,debug安装没有问题,一到打包签名就报了。 环境 win10 jdk17 gradle8 项目依赖情况 博主的greendao是一个独立的module项目,项目目前只适配了java,不支持Kotlin。然后被外部集成。greendao版本…...
Ansible自动化运维实战--通过role远程部署nginx并配置(8/8)
文章目录 1、准备工作2、创建角色结构3、编写任务4、准备配置文件(金甲模板)5、编写变量6、编写处理程序7、编写剧本8、执行剧本Playbook9、验证-游览器访问每台主机的nginx页面 在 Ansible 中,使用角色(Role)来远程部…...
RGB 转HSV空间颜色寻找色块
文章目录 前言一、绿色确定二、红色确定总结 前言 提示:这里可以添加本文要记录的大概内容: 项目需要: 将RGB颜色空间转换为HSV颜色空间以寻找颜色,主要基于以下几个原因: 直观性: HSV颜色空间更符合人类…...
Spring Boot - 数据库集成04 - 集成Redis
Spring boot集成Redis 文章目录 Spring boot集成Redis一:redis基本集成1:RedisTemplate Jedis1.1:RedisTemplate1.2:实现案例1.2.1:依赖引入和属性配置1.2.2:redisConfig配置1.2.3:基础使用 2&…...
C++红黑树详解
文章目录 红黑树概念规则为什么最长路径不超过最短路径的二倍?红黑树的时间复杂度红黑树的结构插入叔叔节点情况的讨论只变色(叔叔存在且为红)抽象的情况变色单旋(叔叔不存在或叔叔存在且为黑)变色双旋(叔叔不存在或叔叔存在且为黑…...
与机器学习相关的概率论重要概念的介绍和说明
概率论一些重要概念的介绍和说明 1、 试验 (1)试验是指在特定条件下,对某种方法、技术、设备或产品(即,事物)进行测试或验证的过程。 (2)易混淆的概念是,实验。实验&…...
60.await与sleep的原理分析 C#例子 WPF例子
在异步任务中使用Thread.Sleep会阻塞当前线程,因其是同步操作,暂停线程执行而不释放资源。这与异步编程旨在避免线程阻塞的目的相冲突。尽管异步方法可能包含其他await调用,Thread.Sleep仍会立即阻塞线程,妨碍其处理其他任务或响应…...
数据库连接池是如何工作的?
连接池是一种用于管理和复用连接(如数据库连接或网络连接)的技术,广泛应用于数据库操作和网络请求中,以提高应用程序的性能和资源利用率。以下是连接池的工作原理和机制的详细解释: 连接池的工作原理 1. 初始化阶段 在应用程序启动时,连接池会根据配置参数预先创建一定…...
2025年01月26日Github流行趋势
项目名称:onlook 项目地址url:https://github.com/onlook-dev/onlook项目语言:TypeScript历史star数:4871今日star数:207项目维护者:Kitenite, drfarrell, iNerdStack, abhiroopc84, apps/dependabot项目简…...
C语言的灵魂——指针(1)
指针是C语言的灵魂,有了指针C语言才能完成一些复杂的程序;没了指针就相当于C语言最精髓的部分被去掉了,可见指针是多么重要。废话不多讲我们直接开始。 指针 一,内存和地址二,编址三,指针变量和地址1&#…...
vue2和vue3指令
Vue 2 和 Vue 3 的指令系统非常相似,但 Vue 3 在指令方面进行了优化和扩展。以下是 Vue 2 和 Vue 3 中指令的对比: 1. 通用指令 这些指令在 Vue 2 和 Vue 3 中都可以使用,功能一致: 指令说明v-bind绑定 HTML 属性或组件 propsv-…...
【超详细】ELK实现日志采集(日志文件、springboot服务项目)进行实时日志采集上报
本文章介绍,Logstash进行自动采集服务器日志文件,并手把手教你如何在springboot项目中配置logstash进行日志自动上报与日志自定义格式输出给logstash。kibana如何进行配置索引模式,可以在kibana中看到采集到的日志 日志流程 logfile-> l…...
微信阅读网站小程序的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
通过配置核查,CentOS操作系统当前无多余的、过期的账户;但CentOS操作系统存在共享账户r***t
通过配置核查,CentOS操作系统当前无多余的、过期的账户;但CentOS操作系统存在共享 核查CentOS操作系统中的用户账户,可以使用以下命令: 查看当前活跃用户: awk -F: /\$1\$/{print $1} /etc/shadow 查看多余账户(非活跃账户&…...
Vue 3 30天精进之旅:Day 05 - 事件处理
引言 在前几天的学习中,我们探讨了Vue实例、计算属性和侦听器。这些概念为我们搭建了Vue应用的基础。今天,我们将专注于事件处理,这是交互式Web应用的核心部分。通过学习如何在Vue中处理事件,你将能够更好地与用户进行交互&#…...
.NET Core跨域
CORS 跨域通讯的问题。解决方案:JSONP、前端代理后端请求、CORS等。CORS原理:在服务器的响应报文头中通过access-control-allow-origin告诉浏览器允许跨域访问的域名。在Program.cs的“var appbuilder.Build()”这句代码之前注册 string[] urls new[] …...
笔试-二维数组2
应用 现有M(1<M<10)个端口组,每个端口组是长度为N(1<N<100),元素均为整数。如果这些端口组间存在2个及以上的元素相同,则认为端口组可以关联合并;若可以关联合并,请用二位数组表示输出结果。其中…...
vue中使用jquery 实现table 拖动改变尺寸
使用 CDN , 降低打包文件的大小在index.html中 <script src"https://.../cdns/jquery-1.12.4.min.js"></script>在 Vue 中使用 jQuery 一旦你引入 jQuery,你可以在 Vue 实例中使用它。有两种主要方式: 1. 使用全局变量 $ jQue…...
使用ensp进行ppp协议综合实验
实验拓扑 实验划分 AR1的Serial3/0/0接口:192.168.1.1/24; AR2的Serial3/0/0接口:192.168.1.2/24; AR2的Serial3/0/1和4/0/0的聚合接口:192.168.2.2/24; AR3的Serial3/0/0和3/0/1的聚合接口:192…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
