微服务学习-服务调用组件 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…...
PDF2WORD万能方法,如何控制Adobe dc pro,自动实现PDF转word
如何用JavaScript控制Adobe DC Pro来自动实现PDF转Word。首先,我需要考虑Adobe DC Pro是否有公开的API或者扩展接口。我记得Adobe Acrobat Pro DC支持JavaScript,但主要是用于表单处理和文档操作,比如Acrobat JavaScript。不过,自…...
Java Web-Tomcat Servlet
Web服务器-Tomcat Web服务器简介 Web 服务器是一种软件程序,它主要用于在网络上接收和处理客户端(如浏览器)发送的 HTTP 请求,并返回相应的网页内容或数据。以下是关于 Web 服务器的详细介绍: 功能 接收请求&#…...
寒假学web--day09
简介 一些魔法函数与php反序列化漏洞 tips 反序列化和类的方法无关,不能把类的方法序列化 将php.exe所在目录放到环境变量中,就可以在终端里通过php.exe ./命令来执行php代码 魔术方法 __construct() 在实例化一个对象时会自动调用,可…...
深度解析:基于Vue 3的教育管理系统架构设计与优化实践
一、项目架构分析 1. 技术栈全景 项目采用 Vue 3 TypeScript Tailwind CSS 技术组合,体现了现代前端开发的三大趋势: 响应式编程:通过Vue 3的Composition API实现细粒度响应 类型安全:约60%的组件采用TypeScript编写 原子化…...
CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(Matlab完整源码和数据)
CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(Matlab完整源码和数据) 目录 CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(Matlab完整源码和数据)预测效果基本介绍 CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测一…...
mysql_store_result的概念和使用案例
mysql_store_result() 是 MySQL C API 中的一个函数,用于检索一个完整的结果集到一个客户端。当执行一个查询(通常是 SELECT 查询)并希望处理所有返回的数据时,可以使用此函数。 概念 mysql_store_result() 函数的原型如下&…...
docker安装MySQL8:docker离线安装MySQL、docker在线安装MySQL、MySQL镜像下载、MySQL配置、MySQL命令
一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull mysql:8.0.41 2、离线包下载 两种方式: 方式一: -)在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -)导出 # 导出镜…...
黑盒/白盒运维监控
运维监控分为黑盒和白盒 黑盒:不深入代码,在系统角度看TPS,延迟等指标 白盒:深入代码分析,通过日志捕捉,以及主动上报告警等来进行监控 黑盒监控: 1. 页面功能:域名是否可访问&…...
奖励模型:解析大语言模型的关键工具
标题:奖励模型:解析大语言模型的关键工具 文章信息摘要: 奖励模型是理解和审核大语言模型(LLM)的重要工具,通过简单的评估方式提供了模型内部表征和性能的深入洞察。它不仅能静态比较模型表现,还可帮助诊断训练问题&a…...
Boot 系统选择U启动
1.进入Boot 系统 F2 或 Del Boot --->Boot 0ption Priorities #4 KingstwongDataTravele 是U盘 调整搭到#1 2.保持重启就好...
001 mybatis入门
文章目录 mybatis是什么ORM是什么ORM框架和MyBatis的区别#{}和${}的区别编码流程UserDaoImpl.javaUserDao.javaUser.javadb.propertiesSqlMapConfig.xmlUserMapper.xmlMybatisTest.javapom.xmluser.sql 表现层 SpringMVC 业务层 Spring 持久层 Mybatis https://mybatis.org/myb…...
【前端SEO】使用Vue.js + Nuxt 框架构建服务端渲染 (SSR) 应用满足SEO需求
Nuxt.js 是一个基于 Vue.js 的通用应用框架,它简化了使用 Vue 构建服务端渲染 (SSR) 应用的流程。除了 SSR 之外,Nuxt.js 还支持静态站点生成(Static Site Generation, SSG),渐进式网络应用(Progressive We…...
sysbench压力测试工具mysql以及postgresql
sysbench压力测试工具mysql以及postgresql sysbench工具安装 [postgresoradb sysbench-1.0.20]$ ./autogen.sh ./autogen.sh: running libtoolize --copy --force libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, config. libtoolize: copying file config/ltm…...
9.中断系统、EXTI外部中断
中断系统原理 中断 中断系统是管理和执行中断的逻辑结构,外部中断是众多能产生中断的外设之一,所以本节我们就借助外部中断来学习一下中断系统。在以后学习其它外设的时候,也是会经常和中断打交道的。 中断:在主程序运行过程中…...
Oracle 12c 中的 CDB和PDB的启动和关闭
一、简介 Oracle 12c引入了多租户架构,允许一个容器数据库(Container Database, CDB)托管多个独立的可插拔数据库(Pluggable Database, PDB)。本文档旨在详细描述如何启动和关闭CDB及PDB。 二、容器数据库 (CDB) 2.1…...
RocketMQ原理—4.消息读写的性能优化
大纲 1.Producer基于队列的消息分发机制 2.Producer基于Hash的有序消息分发 3.Broker如何实现高并发消息数据写入 4.RocketMQ读写队列的运作原理分析 5.Consumer拉取消息的流程原理分析 6.ConsumeQueue的随机位置读取需求分析 7.ConsumeQueue的物理存储结构设计 8.Cons…...
【C++动态规划 网格】2328. 网格图中递增路径的数目|2001
本文涉及知识点 C动态规划 LeetCode2328. 网格图中递增路径的数目 给你一个 m x n 的整数网格图 grid ,你可以从一个格子移动到 4 个方向相邻的任意一个格子。 请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递…...
Web3.0时代的挑战与机遇:以开源2+1链动模式AI智能名片S2B2C商城小程序为例的深度探讨
摘要:Web3.0作为互联网的下一代形态,承载着去中心化、开放性和安全性的重要愿景。然而,其高门槛、用户体验差等问题阻碍了Web3.0的主流化进程。本文旨在深入探讨Web3.0面临的挑战,并提出利用开源21链动模式、AI智能名片及S2B2C商城…...
MySQL(高级特性篇) 12 章——数据库其它调优策略
一、数据库调优的措施 (1)调优的目标 尽可能节省系统资源,以便系统可以提供更大负荷的服务(吞吐量最大)合理的结构设计和参数调整,以提高用户操作的响应速度(响应速度更快)减少系统…...
单片机基础模块学习——DS18B20温度传感器芯片
不知道该往哪走的时候,就往前走。 一、DS18B20芯片原理图 该芯片共有三个引脚,分别为 GND——接地引脚DQ——数据通信引脚VDD——正电源 数据通信用到的是1-Wier协议 优点:占用端口少,电路设计方便 同时该协议要求通过上拉电阻…...
掌握长尾关键词优化技巧提升SEO效果与流量增长策略
内容概要 长尾关键词是指由三个或更多个词组成的关键词,这类关键词通常搜索量相对较低,但在搜索引擎优化(SEO)中的作用却不可忽视。它们能够精确定位用户的需求,因为长尾关键词往往反映了用户更具体的搜索意图。掌握长…...
AAAI2024论文解读|HGPROMPT Bridging Homogeneous and Heterogeneous Graphs
论文标题 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning 跨同构异构图的小样本提示学习 论文链接 HGPROMPT: Bridging Homogeneous and Heterogeneous Graphs for Few-shot Prompt Learning论文下载 论文作者 Xingtong Yu, Yuan…...
高频 SQL 50 题(基础版)_620. 有趣的电影
高频 SQL 50 题(基础版)_620. 有趣的电影 一级目录 表:cinema id 是该表的主键(具有唯一值的列)。 每行包含有关电影名称、类型和评级的信息。 评级为 [0,10] 范围内的小数点后 2 位浮点数。 编写解决方案,找出所有影片描述为 …...
git的理解与使用
本地的git git除了最经典的add commit push用来做版本管理,其实他的分支管理也非常强大 可以说你学好了分支管理,就可以完成团队的配合协作了 git仓库 我们可以使用git init来初始化一个git仓库,只要能看见.git文件夹,就代表这…...
Java进阶(一)
目录 一.Java注解 什么是注解? 内置注解 元注解 二.对象克隆 什么是对象克隆? 为什么用到对象克隆 三.浅克隆深克隆 一.Java注解 什么是注解? java中注解(Annotation)又称java标注,是一种特殊的注释。 可以添加在包,类&…...
zookeeper的介绍和简单使用
1 zookerper介绍 zookeeper是一个开源的分布式协调服务,由Apache软件基金会提供,主要用于解决分布式应用中的数据管理、状态同步和集群协调等问题。通过提供一个高性能、高可用的协调服务,帮助构建可靠的分布式系统。 Zookeeper的特点和功能…...
【学习笔记】深度学习网络-深度前馈网络(MLP)
作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程,深度学习领域研究生必读教材),开始深度学习领域学习,深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中用…...
使用Java技术开发软件详细流程
1. 需求分析 与客户沟通:与客户或项目负责人交流,了解需要开发的软件目标、功能需求、性能要求、使用场景等。例如,如果要开发一个在线购物系统,需要明确用户是否可以浏览商品、添加到购物车、下单支付等功能。收集和整理需求&am…...
Kubectl 与 Helm 详解
在 Kubernetes 生态中,kubectl 和 Helm 是两个核心工具,分别用于直接管理 Kubernetes 资源和简化应用的部署与管理。本文将深入探讨 kubectl 和 Helm 的功能、使用场景、部署与更新方式,并对比它们的优缺点。 1. Kubectl 详解 1.1 什么是 Kubectl? kubectl 是 Kubernetes…...
