声明式服务调用OpenFeign

news/2025/1/12 4:07:53/

文章目录

  • 一. OpenFeign
      • 1. Feign 与 OpenFeign
  • 二. OpenFeign的使用
  • 三. OpenFeign自定义配置
      • 1. 修改日志级别
      • 2. 超时控制
  • 四. OpenFeign性能优化
  • 五. OpenFeign最佳实践
      • 1. 继承
      • 2. 抽取


PS: 本文为作者学习笔记,实际技术参加意义不大,本文将持续改进完善。

一. OpenFeign

OpenFeign是一个声明式的http客户端,SpringCloud生态中服务调用的一个组件。
相关的服务调用组件还有: Feign、Ribbon、LoadBalancer等等
官方地址:点击跳转
其作用就是帮助我们优雅的实现http请求的发送

1. Feign 与 OpenFeign

Feign:
Feign,是Spring Cloud组件中的一个轻量级RESTfulE的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口就可以调用服务注册中心的服务。
依赖:

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

OpenFeign
OpenFeign,是Spring Cloud在Feign的基础上支持了SpringMVC的注解如@RequesMapping等等。OpenFeign的@FeignClienti可以解析,SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
依赖:

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

PS: 其实完全可以将OpenFeign理解为Feign的升级版。

二. OpenFeign的使用

想要使用OpenFeign,首先需要引入OpenFeign的依赖:

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

然后在模块的主启动类上添加 @EnableFeignClients 注解,如下:

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {public static void main(String[] args) {SpringApplication.run(OrderFeignMain80.class,args);}
}

然后就可以开始编写客户端代码(声明式的方式)如下:
在这里插入图片描述
其中 userservice 是注册中心中的服务名、请求方式是 get 、请求路径是 /user/{id}
使用时我们只要使用自动注入的方式生成一个接口实例调用其中的方法即可:

@Autowired
private UserClient userClient;
// 调用
User user = userClient.findById(order.getUserId());

值得注意的是: OpenFeign中集成了ribbon,自带负载均衡。

三. OpenFeign自定义配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:
在这里插入图片描述
日志级别说明:

  1. 【NONE】也是默认的日志级别,就是没有日志
  2. 【BASIC】当发起一次hppt请求时会帮我们记录下来请求什么时候发起的已经什么时候结束的,耗时等基本信息。
  3. 【HEADERS】除了上面basic的基本信息以外,还会带上请求头等信息
  4. 【FULL】在上面basic的基础上还会加上请求体响应体等信息记录下来

PS: 顺嘴提一句失败重试机制,就是请求服务失败,一段时间后会自动请求其他相同业务的服务实例,直到拿到结果,或者全部请求失败。

1. 修改日志级别

一般我们使用的最多的就是修改日志级别,一般有两种方式,一种是通过配置来修改日志级别,另一种方式是通过java代码的方式进行日志级别的修改:
方式一: 配置文件方式
全局配置:

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

局部配置:

feign: client:config:userservice:  loggerLevel: FULL  #日志级别

方式二: java代码配置方式
使用Bean的方式进行配置:

public class FeignclientConfiguration{@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC;}
}

如果是全局配置则放到: 启动类上面的注解

@EnableFeignclients(defaultConfiguration FeignclientConfiguration.class)

如果是局部配置则放到: 调用接口上的注解,通过value的值指定配置的微服务名

@Feignclient(value "userservice",configuration FeignclientConfiguration.class)

2. 超时控制

根据服务业务功能的不同服务接口调用的时间也会不同,但是OpenFeign的底层是ribbon,默认的等待时间是1秒钟,超过一秒调用时间就会报错, 这显然是不合理的。
为了避免上述情况这时我们就需要在配置文件中修改等待的时间:

#设置feign客户端超时时间(OpenFeign默认支ribbon)
ribbon:#指的是建立连接所用的时间,适用于网路状况正常的情况下,两端连接所用的时间ReadTimeout: 5000  #5 秒的意思#指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000

四. OpenFeign性能优化

OpenFeign的性能虽然已经很不错,但是还是存在优化的余地,底层客户端实现:

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

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

  1. 使用连接池代替默认的URLConnection
  2. 日志级别,最好用basic或none (减少性能损耗)

关于日志上一章已经讲解过了,那么接下来还是着重聊修改连接池,这里就以修改为HttpClient为例子:
首先先引入依赖:

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

然后进行连接池的配置:
具体参数根据业务需求调整

feign: client:config:default:loggerLevel: NONE # 日志级别httpclient:enabled: true #开启feign对Httpclient的支持max-connections: 200 #最大的连接数max-connections-per-route: 50 #每个路径的最大连接数

五. OpenFeign最佳实践

1. 继承

方式一: 给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。
在这里插入图片描述
但是这种方法也存在一定的问题,比如耦合度比较高,且方法参数也是继承不下来的。

2. 抽取

方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的pojo、默认的Feign配置都放到这个模块中,消费者通过引入该模块调用方法发送http请求。
在这里插入图片描述
但是这种方法也是有缺点的,可能会将一些多余的调用方法引入到模块。
值得注意的是:消费者启动类上还是得使用@EnableFeignClients注解
在这里插入图片描述


http://www.ppmy.cn/news/6896.html

相关文章

JavaSE笔记——异常、断言

文章目录前言一、处 理 错 误1.异常分类2.声明受查异常3.如何抛出异常4.创建异常类二、捕获异常1.捕获异常2.捕获多个异常3.再次抛出异常与异常链4.finally 子句5.带资源的 try 语句三、使用断言1.断言的概念2.启用和禁用断言3.使用断言完成参数检查总结前言 在现实世界中却充…

使用matplotlib画图 + python色彩大全

目录画线画点散点画点的形状、线的形状画点线在特定位置写文字plt.legend()中图例的位置方法一 plt.legend(loc4)方法二 plt.legend(bbox_to_anchor(num1, num2))方法三 bbox_to_anchor(1.05, 1), loc2, borderaxespad0保存图片指定图片大小网格线根据自己的需求做了一个画图的…

OPENGL ES 2.0 知识串讲 (9) ——OPENGL ES 详解III(纹理)

上节回顾 更多音视频知识请关注公众号&#xff1a;进击的代码家 上面一节课&#xff0c;我们学习了一个OpenGL ES程序必须具备的一些API&#xff0c;从准备shader&#xff0c;到传入绘制信息&#xff0c;到最后的执行绘制命令。然而在上节课结束的时候&#xff0c;我们也提到…

IT30--IT与业务业务与ITIT价值(3年之约已满)

从大学开始。。。 读大学前压根就没有见过计算机这个东西&#xff08;不得不感慨信息技术发展之快&#xff09;。可能因为高考数学考的还不错的原因&#xff0c;选择了计算机这个专业&#xff0c;后来研究生读的也是计算机的相关专业。当时班里的女生少&#xff0c;但没想到一…

跟我学c++中级篇——zero overhead abstraction

一、零成本抽象&#xff08;zero overhead abstraction&#xff09; 什么是零成本抽象&#xff1f;这东西不是国人提出的&#xff0c;那就得用人家提出的人的解释&#xff1a;“What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand c…

详细介绍关于自定义类型:结构体、枚举、联合【c语言】

文章目录结构体结构体的声名特殊的声明结构成员的类型结构的自引用结构体变量的定义和初始化结构体内存对齐修改默认对齐数结构体变量访问成员结构体传参结构体实现位段&#xff08;位段的填充&可移植性&#xff09;位段的内存分配位段的跨平台问题枚举枚举类型的定义枚举的…

记一次线上fullgc----数据库查询返回大量数据

背景 某服务线上16台机器&#xff0c;晚上八点左右有4台机器突然出现fullgc&#xff0c;而且不止一次 处理流程 1&#xff09;发现机器full gc告警时&#xff0c;立即dump出机器内存快照 2&#xff09;下线问题机器 3&#xff09;分析内存快照&#xff0c;找到问题对象 可以…

[Flask]数据库的连接和操作

一、安装连接程序 在控制台中使用语句 pip install pymysql 即可安装 同时为了使用ORM对数据库进行操作&#xff08;而非sql语句&#xff09;&#xff0c;还需要安装SQLAlchemy pip install flask-sqlalchemy 二、使用Navicat管理数据库 安装Navicat软件&#xff0c;本体需要…