Spring Cloud - HTTP 客户端 Feign 、自定义配置、优化、最佳实践

目录

一、Feign 是什么,有什么用呢?

二、Feign 客户端的使用

2.1、远程调用

1.引入依赖

2.在order-service(发起远程调用的微服务)的启动类添加注解开启Feign的功能

3.编写 Feign 客户端

4.通过 Feign 客户端发起远程调用

2.2、自定义 Feign 配置

1.配置文件方式

2.java代码方式

2.3、Feign 的性能优化

1.引入依赖

2.配置连接池

2.4、Feign 的最佳实践

1.方式一:给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

2.方式二(推荐):将FeignClient抽取为独立模块,并且把接口有关的POJO(实体类)、默认的Feign配置都放到这个模块中,提供给所有消费者使用


一、Feign 是什么,有什么用呢?


以往我们是通过 RestTemplate 发起远程调用,如下

存在问题如下:

  • 代码可读性差,编程体验不统一
  • 参数复杂URL难以维护

Feign  是一个声明式的 http 客户端,其作用就是用来把我们解决上述问题的~

二、Feign 客户端的使用


2.1、远程调用

主要分为以下步骤:

1.引入依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> 
</dependency>

2.order-service(发起远程调用的微服务)的启动类添加注解开启Feign的功能

3.编写 Feign 客户端

主要是基于SpringMVC的注解来声明远程调用的信息,比如:

  • 服务名称:userservice
  • 请求方式:GET
  • 请求路径:/user/{id}
  • 请求参数:Long id
  • 返回值类型:User
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@Component
@FeignClient("userservice")
public interface UserClients {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);}

4.通过 Feign 客户端发起远程调用

用 Feign 来代替 RestTemplate 是不是十分优雅~

2.2、自定义 Feign 配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下

类型

作用

说明

feign.Logger.Level

修改日志级别

包含四种不同的级别:NONEBASICHEADERSFULL

feign.codec.Decoder

响应结果的解析器

http远程调用的结果做解析,例如解析json字符串为java对象

feign.codec.Encoder

请求参数编码

将请求参数编码,便于通过http请求发送

feign. Contract

支持的注解格式

默认是SpringMVC的注解

feign. Retryer

失败重试机制

请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

我们最常使用的就是 修改日志级别 ,其他的可以暂时不考虑~

配置Feign日志有以下两种方式:

1.配置文件方式

a、全局生效

feign:client:config: default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置loggerLevel: FULL #  日志级别 

b、局部生效

feign:client:config: userservice: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置loggerLevel: FULL #  日志级别 

2.java代码方式

首先需要声明一个 Bean,如下

public class FeignClientConfiguration {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC;  //一般使用 BASIC 级别,因为太多的日志信息影响效率}
}

情况一:如果是全局配置,则把它放到@EnableFeignClients这个注解中:

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class) 

情况二:如果是局部配置,则把它放到@FeignClient这个注解中:

@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class) 

2.3、Feign 的性能优化

Feign 的底层客户端实现:

  • URLConnection:默认实现,不支持连接池
  • Apache HttpClient :支持连接池
  • OKHttp:支持连接池

因此优化Feign的性能主要包括:

  1. 使用连接池代替默认的URLConnection
  2. 日志级别,最好用basic或none

因此使用 HttpClient 或 OKHttp 代替 URLConnection

1.引入依赖

<!--httpClient的依赖 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>

2.配置连接池

feign:client:config:default: # default全局的配置loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息 httpclient:enabled: true # 开启feign对HttpClient的支持max-connections: 200 # 最大的连接数max-connections-per-route: 50 # 每个路径的最大连接数

2.4、Feign 的最佳实践

1.方式一:给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

仔细观察我们可以发现, Feign 发起远程调用的接口和接收远程调用请求的 controller 层实现代码是一样的,因此,我们我可以把他们的共性提取出来,写成一个公开的接口,将来我们使用的时候只需要继承这个接口即可,如下图

 

 但这种方式存在一定的问题,以下是官方提出的问题:

也就是说

  • 服务紧耦合
  • 不适用于 Spring MVC (父接口参数列表中的映射不会被继承

2.方式二(推荐):FeignClient抽取为独立模块,并且把接口有关的POJO(实体类)、默认的Feign配置都放到这个模块中,提供给所有消费者使用

 具体步骤:

1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖

        <!--feign 客户端依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

 


2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中

 


3.在order-service中引入feign-api的依赖

 

4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包

5.重启测试

这个时候你重启项目,项目必然会报以下错误

 

为什么 UserClients 没有对应的对象呢?

UserClients 之前有对象是因为扫描到 @FeignClient 注解注入了对象 ,而现在 order-service 扫描包的范围是启动类下的包,但由于我们刚刚把 UserClients 挪到了 feign-api 这个 Module 中,因此,扫描不到该注解,无法注入对象。

总而言之:当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。

有以下两种解决方式:

方式一:指定FeignClient所在包

@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

这种方式会将指定包下的所有东西都拿过来。

方式二(推荐):指定FeignClient字节码

@EnableFeignClients(clients = {UserClient.class})

这种方式是精准打击,只拿指定的类,效率上更推荐使用,用哪个,就指定哪个.

 

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

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

相关文章

eNSP-静态路由表的配置

eNSP-静态路由表的配置 文章目录 eNSP-静态路由表的配置一、拓扑结构二、关键语句三、完整代码四、测试验证 一、拓扑结构 二、关键语句 ip route-static x.x.x.x y z.z.z.z 语法&#xff1a;目标网段 掩码 下一跳 例如 PC1所在网段访问PC2所在网段 在AR1中输入 ip route-st…

新加坡 PBM 是可编程数字货币的重要创新

一周以前我们在卢旺达开会的时候&#xff0c;新加坡 MAS 在现场发布了 Purpose Bound Money &#xff08;PBM&#xff09; 的技术白皮书。行业媒体发了几条新闻&#xff0c;然后就放过去了。实际上 PBM 代表着货币当局对于数字货币编程问题迄今为止最深度的思考&#xff0c;其白…

分布式软件架构——客户端缓存

浏览器的客户端缓存 当万维网刚刚出现的时候&#xff0c;浏览器的缓存机制差不多就已经存在了。在 HTTP 协议设计之初&#xff0c;人们便确定了服务端与客户端之间“无状态”&#xff08;Stateless&#xff09;的交互原则&#xff0c;即要求客户端的每次请求是独立的&#xff…

LeetCode 打卡day48--打家劫舍I, II, III

一个人的朝圣 — LeetCode打卡第48天 知识总结 Leetcode 198. 打家劫舍题目说明代码说明 Leetcode 213. 打家劫舍 II题目说明代码说明 Leetcode 337. 打家劫舍 III题目说明代码说明 知识总结 今天全是打家劫舍系列的题目, 还挺有意思的 Leetcode 198. 打家劫舍 题目链接 题目…

【C++初阶(二)】缺省参数以及函数重载

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C初阶之路⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习排序知识   &#x1f51d;&#x1f51d; 缺省参数&#xff06;函数重载 1. 前言2. 缺…

python学习——函数

一、函数的定义 函数就是执行特定任务和完成特定功能的一段代码。使用函数可以对代码进行复用&#xff0c;提高代码的可维护性和可读性&#xff0c;使得程序便于调试。 二、函数的创建 创建格式 #创建和格式 def 函数名&#xff08;[参数]&#xff09;:函数体[return xxx]举例…

MySQL:库的操作和表的操作(内含MySQL数据类型讲解)

进入数据库的数据目录 cd var/lib/mysql 库的操作 创建数据库 创建数据库的本质是创建目录。 创建数据库时有两个编码集&#xff1a;1.数据库编码集&#xff08;存储时使用&#xff09;2.进行字段比对读取时使用的编码方式&#xff09; 语法&#xff1a; CREATE DATABASE …

7、Redis复制(replica)

Redis复制(replica) 是什么&#xff1f; 就是主从复制&#xff0c;master以写为主&#xff0c;Slave以读为主。当master数据变化的时候&#xff0c;自动将新的数据异步同步到其它slave数据库 读写分离 容灾恢复 数据备份 水平扩容支撑高并发 案例演示 架构说明 一个Master两个…

微服务系列文章之 seata 事务模式

XA模式 XA 规范 是 X/Open 组织定义的分布式事务处理&#xff08;DTP&#xff0c;Distributed Transaction Processing&#xff09;标准。 XA 规范 描述了全局的TM与局部的RM之间的接口&#xff0c;几乎所有主流的数据库都对 XA 规范 提供了支持。 两阶段提交 XA是规范&…

深度学习优化算法

梯度下降算法 随机梯度下降。随机梯度下降是指每次迭代在训练数据中随机抽取一个数据计算梯度来更新模型得参数。随机梯度下降容易受到噪声干扰,训练时间长,代价函数最终会围绕全局最小值或者局部极小值震荡。批量梯度下降。每次迭代时使用所有的训练数据来计算梯度更新模型的…

UE5 录制透明png序列帧

以下是在 Unreal Engine 5 中录制透明 PNG 序列帧的详细步骤&#xff1a; 步骤1&#xff1a;创建一个场景 步骤2&#xff1a;打开序列录制器 在 Unreal Engine 5 中&#xff0c;首先需要打开序列录制器。你可以通过点击顶部菜单栏的 窗口 > 开发人员工具 > 序列录制器 …

WEB漏洞-XXEXML之利用检测绕过全解(39)

#概念 xml&#xff1a;xml被设计成传输和储存数据&#xff0c;XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素&#xff0c;其焦点是数据的内容。就类似于一种数据的格式&#xff0c;代码类的一些东西&#xff1b; xxe&#xff1a;是xml上面的一个漏洞&#xff0c;…