分享Spring Cloud OpenFeign 的五个优化技巧
作者:??JAVA小也???? 发布时间:2022-06-23 08:53:30
前言:
OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件。它的出现就是为了替代已经进入停更维护状态的 Feign(Netflix Feign),同时它也是 Spring 官方的顶级开源项目。我们在日常的开发中使用它的频率也很高,而 OpenFeign 有一些实用的小技巧,配置之后可以让 OpenFeign 更好的运行,所以本文我们就来盘点一下(也欢迎各位老铁评论区留言补充)。
一、超时优化
OpenFeign 底层内置了 Ribbon 框架,并且使用了 Ribbon 的请求连接超时时间和请求处理超时时间作为其超时时间,而 Ribbon 默认的请求连接超时时间和请求处理超时时间都是 1s
如下源码所示:
所有当我们使用 OpenFeign 调用了服务接口超过 1s,就会出现以下错误:
因为 1s 确实太短了,因此我们需要手动设置 OpenFeign 的超时时间以保证它能正确的处理业务。
OpenFeign 的超时时间有以下两种更改方法:
通过修改 Ribbon 的超时时间,被动的修改 OpenFeign 的超时时间。
直接修改 OpenFeign 的超时时间(推荐使用)。
1、设置Ribbon超时时间
在项目配置文件 application.yml 中添加以下配置:
ribbon:
ReadTimeout: 5000 # 请求连接的超时时间
ConnectionTimeout: 10000 # 请求处理的超时时间
2、设置OpenFeign超时时间
在项目配置文件 application.yml 中添加以下配置:
feign:
client:
config:
default: # 设置的全局超时时间
connectTimeout: 2000 # 请求连接的超时时间
readTimeout: 5000 # 请求处理的超时时间
推荐使用此方式来设置 OpenFeign 的超时时间,因为这样的(配置)语义更明确。
二、请求连接优化
OpenFeign 底层通信组件默认使用 JDK 自带的 URLConnection 对象进行 HTTP 请求的,因为没有使用连接池,所以性能不是很好。我们可以将 OpenFeign 的通讯组件,手动替换成像 Apache HttpClient 或 OKHttp 这样的专用通信组件,这些的专用通信组件自带连接池可以更好地对 HTTP 连接对象进行重用与管理,同时也能大大的提升 HTTP 请求的效率。接下来我以 Apache HttpClient 为例,演示一下专用通讯组件的使用。
1、引入Apache HttpClient依赖
在项目的依赖管理文件 pom.xml 中添加以下配置:
<!-- 添加 openfeign 框架依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 添加 httpclient 框架依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2、开启Apache HttpClient使用
启动 Apache HttpClient 组件,在项目配置文件 application.yml 中添加以下配置,:
feign:
client:
httpclient: # 开启 HttpClient
enabled: true
验证 Apache HttpClient 配置是否生效,可以在 feign.SynchronousMethodHandler#executeAndDecode 方法上打断点就可以看到了,
如下图所示:
三、数据压缩
OpenFeign 默认不会开启数据压缩功能,但我们可以手动的开启它的 Gzip 压缩功能,这样可以极大的提高宽带利用率和加速数据的传输速度,在项目配置文件 application.yml 中添加以下配置:
feign:
compression:
request:
enabled: true # 开启请求数据的压缩功能
mime-types: text/xml,application/xml, application/json # 压缩类型
min-request-size: 1024 # 最小压缩值标准,当数据大于 1024 才会进行压缩
response:
enabled: true # 开启响应数据压缩功能
PS:如果服务消费端的 CPU 资源比较紧张的话,建议不要开启数据的压缩功能,因为数据压缩和解压都需要消耗 CPU 的资源,这样反而会给 CPU 增加了额外的负担,也会导致系统性能降低。
四、负载均衡优化
OpenFeign 底层使用的是 Ribbon 做负载均衡的,查看源码我们可以看到它默认的负载均衡策略是轮询策略,
如下图所示:
然而除了轮询策略之外,我们还有其他 6 种内置的负载均衡策略可以选择,这些负载均衡策略如下:
权重策略: WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。它的实现原理是,刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被选中的概率也越大。
最小连接数策略: BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。
区域敏感策略: ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。
可用敏感性策略: AvailabilityFilteringRule,先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例。
随机策略: RandomRule,从服务提供者的列表中随机选择一个服务实例。
重试策略: RetryRule,按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。
出于性能方面的考虑,我们可以选择用权重策略或区域敏感策略来替代轮询策略,因为这样的执行效率最高。
五、日志级别优化
OpenFeign 提供了日志增强功能,它的日志级别有以下几个:
NONE: 默认的,不显示任何日志。
BASIC: 仅记录请求方法、URL、响应状态码及执行时间。
HEADERS: 除了 BASIC 中定义的信息之外,还有请求和响应的头信息。
FULL: 除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
我们可以通过配置文件来设置日志级别,配置信息如下:
logging:
level:
cn.myjszl.service: debug
其中 cn.myjszl.service 为 OpenFeign 接口所在的包名。虽然 OpenFeign 默认是不输出任何日志,但在开发阶段可能会被修改,因此在生产环境中,我们应仔细检查并设置合理的日志级别,以提高 OpenFeign 的运行效率。
修改 OpenFeign 的超时时间,让 OpenFeign 能够正确的处理业务。
通过配置专用的通信组件 Apache HttpClient 或 OKHttp,让 OpenFeign 可以更好地对 HTTP 连接对象进行重用和管理,以提高其性能。
开启数据压缩功能,可以提高宽带利用率和加速数据传输速度。
使用合适的负载均衡策略来替换默认的轮询负载均衡策略,已获得更好的执行效率。
检查生成环境中 OpenFeign 的日志级别,选择合适的日志输出级别,防止无效的日志输出。
来源:https://juejin.cn/post/7101216161609547812


猜你喜欢
- 本文实例为大家分享了Java实现带图形界面聊天程序的具体代码,供大家参考,具体内容如下ServerDemo01.javaimport jav
- 本文实例讲述了Android自定义个性化的Dialog。分享给大家供大家参考,具体如下:Dialog:mDialog = new Dialo
- 只需要下载相应的zip包,不需装什么手机助手。1、下载相应zip包(ROM)http://download.mokeedev.com/比如我
- 现在的项目基本上都是java web项目,所以导入jar包会出现问题,主要介绍一下java项目与javaweb项目的区别:java项目:在c
- 在Java中,泛型的引入是为了在编译时提供强类型检查和支持泛型编程。为了实现泛型,Java编译器应用类型擦除实现: &
- 本文主要对SpringBoot2.x参数校验进行简单总结,其中SpringBoot使用的2.4.5版本。一、引入依赖<dependen
- 本文实例为大家分享了Java身份证号码校验工具类的具体代码,供大家参考,具体内容如下import java.text.ParseExcept
- 解决方法有以下3种1、在Edittext中加入以下属性android:cursorVisible="true"andro
- 在System.Text.RegularExpression命名空间里,有正则表达式方法。using System.Collections.
- file.mkdir()创建单级文件夹,file.mkdirs()创建多级文件夹,file.createNewFile()创建的是一个文件。
- Android 使用FragmentTabhost代替Tabhost前言:现在Fragment使用越来越广了,虽然Fragment寄生在Ac
- 本文实例讲述了Android编程获取网络连接方式及判断手机卡所属运营商的方法。分享给大家供大家参考,具体如下:问题:项目中写的网络模块,感觉
- 开发环境: IDEA 2022.1.41. 概述虽然webservice这块使用很少,但在局域网作服务还是相当不错。今天突生想法,想做一个来
- 本文实例讲述了C#调用VB进行简繁转换的方法。分享给大家供大家参考。具体分析如下:首先在C#项目中引用Microsoft.VisualBas
- 一、问题背景在Intellij idea中,新建Maven项目,在魔项目中新建多个模块,发现模块间相互调用失败二、问题原因模块间无法相互引用
- spring boot metrics是什么?针对应用监控指标暴露,spring boot有一套完整的解决方案,并且内置了好很多的指标收集器
- 上篇文章给大家介绍了springboot对接第三方微信授权及获取用户的头像和昵称等等1 账户注销1.1 在SecurityConfig中加入
- 前言最近业务开发部门因为开发环境和测试环境共用一个maven私仓,导致他们开发环境的API包和测试环境的API包发生了覆盖现象。于是他们向我
- 目录什么是Spring的占位符?Spring什么时候去解析并占位符什么是Spring的占位符?在以前的Spring Xml配置中我们可能会有
- 关于unicode和utf的关系,可以简单的记忆:Unicode是一个编码组织、一个编码规范、在java中指utf-16;utf是Unico