微服务学习-服务调用组件 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 实现全局生效,对所有的微服务调用者都生效。

    1. 定义一个配置类,指定日志级别
// 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置@Configuration
@Configuration
public class FeignConfig {/*** 日志级别* @return*/@Beanpublic Logger.Level feignLoggerLevel(){return Logger.Level.FULL;}}
    1. 在 application.yml 中配置 Client 的日志级别才能正常输出日志

格式:logging.level.feign 接口包路径=debug

logging:level:com.icoolkj.mall.user.openfeign.demo.feign: debug
    1. 重启测试

分别选择日志级别进行测试,查看控制台输出结果信息。

局部生效:让指定的微服务生效,在 @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 信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/7321.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙模块概念和应用启动相关类(HAP、HAR、HSP、AbilityStage、UIAbility、WindowStage、window)

目录 鸿蒙模块概念 HAP entry feature har shared 使用场景 HAP、HAR、HSP介绍 HAP、HAR、HSP开发 应用的启动 AbilityStage UIAbility WindowStage Window 拉起应用到显示到前台流程 鸿蒙模块概念 HAP hap包是手机安装的最小单元&#xff0c;1个app包含一个或…

想品客老师的第六天:函数

函数基础的部分写在这里 函数声明 在js里万物皆对象&#xff0c;函数也可以用对象的方式定义 let func new Function("title", "console.log(title)");func(我是参数title); 也可以对函数赋值&#xff1a; let cms function (title) {console.log(tit…

Python:元组构造式和字典推导式

&#xff08;Python 元组构造式和字典推导式整理笔记&#xff09; 1. 元组构造式 1.1 创建元组 使用圆括号&#xff1a; tuple1 (1, 2.5, (three, four), [True, 5], False) print(tuple1) # 输出: (1, 2.5, (three, four), [True, 5], False) 省略圆括号&#xff1a; tup…

Linux之Tcp粘包笔记

目录 一.网络传输四层模型 二.数据传输中数据包传输的两个限制概念 三.数据传输的中粘包问题 四.数据组装的原因 Nagle算法原理: 五.关闭Nagle优化处理粘包问题吗&#xff1f; 六.粘包处理方法 a.设置消息边界&#xff1a; b.定义消息长度&#xff1a; 七.UDP是否会出…

【C语言算法刷题】第2题 图论 dijkastra

题目描述 一个局域网内有很多台电脑&#xff0c;分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样&#xff0c;所以感染时间不一样&#xff0c;感染时间用 t 表示。 其中网络内一台电脑被病毒感染&#xff0c;求其感染网络内所有的电脑最少需要多长时间。如果最后有电脑不…

软件测试压力太大了怎么办?

本文其实是知乎上针对一个问题的回答&#xff1a; 目前在做软件测试&#xff0c;主要负责的是手机端的项目测试&#xff0c;项目迭代很快&#xff0c;每次上线前验正式都会发现一些之前验测试包时候没有发现的问题&#xff0c;压力太大了&#xff0c;应该怎么调整 看过我之前其…

枚举与模拟 练习

练习题基于《C/C程序设计竞赛真题实战特训教程&#xff08;图解版&#xff09;》 目录 1.1 卡片 题目描述 代码实现 题解笔记 总评 注意点 重点解释 1.2 回文日期 题目描述 输入描述 输出描述 代码实现 题解笔记 总评 注意点 重点解释 1.1 卡片 题目描述 小蓝…

Redis高阶5-布隆过滤器

Redis布隆过滤器 ​ 由一个初始值都为零的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素 目的减少内存占用方式不保存数据信息&#xff0c;只是在内存中做一个是否存在的标记flag 布隆过滤器&#xff08;英语&#xff1a;Bloom Filter&#xff0…

vim如何设置自动缩进

:set autoindent 设置自动缩进 :set noautoindent 取消自动缩进 &#xff08;vim如何使设置自动缩进永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

检测到联想鼠标自动调出运行窗口,鼠标自己作为键盘操作

联想鼠标会自动时不时的调用“运行”窗口 然后鼠标自己作为键盘输入 然后打开这个网页 &#xff08;不是点击了什么鼠标外加按键&#xff0c;这个鼠标除了左右和中间滚轮&#xff0c;没有其他按键了&#xff09;

(Halcon)轮廓等分切割(项目分析)

目标&#xff1a;获取绿色圆所在位置&#xff08;可用于点焊/点胶引导&#xff09; 实现思路 一&#xff0c;相机标定板标定&#xff08;如果实战用于点焊/点胶引导需要做图像畸变校正以减小误差&#xff09; 相机标定 如何做一个C#仿Halcon Calibration插件-CSDN博客 二&…

Java面试题2025-Mysql

1.什么是BufferPool&#xff1f; Buffer Pool基本概念 Buffer Pool&#xff1a;缓冲池&#xff0c;简称BP。其作用是用来缓存表数据与索引数据&#xff0c;减少磁盘IO操作&#xff0c;提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…

开始步入达梦中级dba

分析内存使用需要的方法之一 disql /nolog conn sysdba/sysdbaselect value from v$parameter where nameMEMORY_LEAK_CHECK; SP_SET_PARA_VALUE(0,MEMORY_LEAK_CHECK,1); select * from V$MEM_REGINFO; select * from V$MEM_HEAP;

UE求职Demo开发日志#7 强化属性完善

1 实现思路设计 定义一个结构体记录技能树一个单元的信息&#xff0c;命名为FStrengthenCellInfo&#xff0c;一个TArray记录技能树整体信息&#xff0c;需要以下信息&#xff1a; 1.TArray前置技能index 2.FString 描述文本 3.TArray<FMyItemInfo>激活需要的物品ID和…

Qt中QVariant的使用

1.使用QVariant实现不同类型数据的相加 方法&#xff1a;通过type函数返回数值的类型&#xff0c;然后通过setValue来构造一个QVariant类型的返回值。 函数&#xff1a; QVariant mainPage::dataPlus(QVariant a, QVariant b) {QVariant ret;if ((a.type() QVariant::Int) &a…

做Midjourney最好图文教程-提示词公式以及高级参数讲解

先说Midjourney万能公式 填写在绘图提示词框里的内容就是提示词&#xff0c;也叫prompt 用途&#xff1a;让Midjourney生成对应图片&#xff08;符合提示词所描述内容的图片&#xff09;&#xff0c;控制图片生成方向种类&#xff1a;文本提示、图像提示、参数提示&#xff0…

【论文阅读】RAG-Reward: Optimizing RAG with Reward Modeling and RLHF

研究背景 研究问题&#xff1a;这篇文章要解决的问题是如何优化检索增强生成&#xff08;RAG&#xff09;系统&#xff0c;特别是通过奖励建模和人类反馈强化学习&#xff08;RLHF&#xff09;来提高大型语言模型&#xff08;LLMs&#xff09;在RAG任务中的效果。研究难点&…

《Trustzone/TEE/安全从入门到精通-标准版》

CSDN学院课程连接:https://edu.csdn.net/course/detail/39573 讲师介绍 拥有 12 年手机安全、汽车安全、芯片安全开发经验,擅长 Trustzone/TEE/ 安全的设计与开发,对 ARM 架构的安全领域有着深入的研究和丰富的实践经验,能够将复杂的安全知识和处理器架构知识进行系统整…

Pyecharts之地图图表的强大功能

在数据可视化领域中&#xff0c;地图图表是一种强大的工具&#xff0c;能够直观地展现与地理位置相关的数据信息&#xff0c;帮助我们更好地洞察数据的地域特征和分布规律。Pyecharts 为我们提供了丰富的地图图表功能&#xff0c;让我们可以轻松实现各种地理信息的可视化展示。…

政安晨的AI大模型训练实践三:熟悉一下LF训练模型的WebUI

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 目录 启动WebUI 微调模型 LLaMA-Factory 支持通过 WebUI 零代码微调大语言模型。 启动Web…