Spring Cloud OpenFeign 的 5 个优化小技巧!

6f0212469eaa669c7bc30f22220b43b8.png

作者 | 磊哥

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件。它的出现就是为了替代已经进入停更维护状态的 Feign(Netflix Feign),同时它也是 Spring 官方的顶级开源项目。我们在日常的开发中使用它的频率也很高,而 OpenFeign 有一些实用的小技巧,配置之后可以让 OpenFeign 更好的运行,所以本文我们就来盘点一下(也欢迎各位老铁评论区留言补充)。

1.超时优化

OpenFeign 底层内置了 Ribbon 框架,并且使用了 Ribbon 的请求连接超时时间和请求处理超时时间作为其超时时间,而 Ribbon 默认的请求连接超时时间和请求处理超时时间都是 1s,如下源码所示:549c418834bd4ca41d2a001f678caed3.png所有当我们使用 OpenFeign 调用了服务接口超过 1s,就会出现以下错误:a162057eabe60c4615bc6b75b707e6b6.png因为 1s 确实太短了,因此我们需要手动设置 OpenFeign 的超时时间以保证它能正确的处理业务。OpenFeign 的超时时间有以下两种更改方法:

  1. 通过修改 Ribbon 的超时时间,被动的修改 OpenFeign 的超时时间。

  2. 直接修改 OpenFeign 的超时时间(推荐使用)。

    1.1 设置Ribbon超时时间

    在项目配置文件 application.yml 中添加以下配置:

    ribbon:
    ReadTimeout: 5000 # 请求连接的超时时间
    ConnectionTimeout: 10000 # 请求处理的超时时间

    1.2 设置OpenFeign超时时间

    在项目配置文件 application.yml 中添加以下配置:

    feign:
    client:config:default: # 设置的全局超时时间connectTimeout: 2000 # 请求连接的超时时间readTimeout: 5000 # 请求处理的超时时间

    推荐使用此方式来设置 OpenFeign 的超时时间,因为这样的(配置)语义更明确。

    2.请求连接优化

    OpenFeign 底层通信组件默认使用 JDK 自带的 URLConnection 对象进行 HTTP 请求的,因为没有使用连接池,所以性能不是很好。我们可以将 OpenFeign 的通讯组件,手动替换成像 Apache HttpClient 或 OKHttp 这样的专用通信组件,这些的专用通信组件自带连接池可以更好地对 HTTP 连接对象进行重用与管理,同时也能大大的提升 HTTP 请求的效率。接下来我以 Apache HttpClient 为例,演示一下专用通讯组件的使用。

    2.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.2 开启Apache HttpClient使用

    启动 Apache HttpClient 组件,在项目配置文件 application.yml 中添加以下配置,:

    feign:
    client:httpclient: # 开启 HttpClientenabled: true

    验证 Apache HttpClient 配置是否生效,可以在 feign.SynchronousMethodHandler#executeAndDecode 方法上打断点就可以看到了,如下图所示:b327454f6c65b4a67d7e49a38c0d256a.png

    3.数据压缩

    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 增加了额外的负担,也会导致系统性能降低。

4.负载均衡优化

OpenFeign 底层使用的是 Ribbon 做负载均衡的,查看源码我们可以看到它默认的负载均衡策略是轮询策略,如下图所示:0f1dd75363b2d6ca32cac903d86c1b6f.png然而除了轮询策略之外,我们还有其他 6 种内置的负载均衡策略可以选择,这些负载均衡策略如下:

  1. 权重策略:WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。它的实现原理是,刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被选中的概率也越大。

  2. 最小连接数策略:BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。

  3. 区域敏感策略:ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。

  4. 可用敏感性策略:AvailabilityFilteringRule,先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例。

  5. 随机策略:RandomRule,从服务提供者的列表中随机选择一个服务实例。

  6. 重试策略:RetryRule,按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。

出于性能方面的考虑,我们可以选择用权重策略或区域敏感策略来替代轮询策略,因为这样的执行效率最高。

5.日志级别优化

OpenFeign 提供了日志增强功能,它的日志级别有以下几个:

  • NONE:默认的,不显示任何日志。

  • BASIC:仅记录请求方法、URL、响应状态码及执行时间。

  • HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息。

  • FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

我们可以通过配置文件来设置日志级别,配置信息如下:

logging:level:cn.myjszl.service: debug

其中 cn.myjszl.service 为 OpenFeign 接口所在的包名。虽然 OpenFeign 默认是不输出任何日志,但在开发阶段可能会被修改,因此在生产环境中,我们应仔细检查并设置合理的日志级别,以提高 OpenFeign 的运行效率

总结

OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件,在生产环境中我们可以通过以下配置来优化 OpenFeign 的运行:

  1. 修改 OpenFeign 的超时时间,让 OpenFeign 能够正确的处理业务;

  2. 通过配置专用的通信组件 Apache HttpClient 或 OKHttp,让 OpenFeign 可以更好地对 HTTP 连接对象进行重用和管理,以提高其性能;

  3. 开启数据压缩功能,可以提高宽带利用率和加速数据传输速度;

  4. 使用合适的负载均衡策略来替换默认的轮询负载均衡策略,已获得更好的执行效率;

  5. 检查生成环境中 OpenFeign 的日志级别,选择合适的日志输出级别,防止无效的日志输出。

参考 && 鸣谢

juejin.cn/post/7010555899240513543

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java中文社群

Java面试合集:https://gitee.com/mydb/interview

1da6458d9616b68faeb049acc6bb98c8.gif

往期推荐

cabb26e28334a21800b93e3667fda47d.png

SpringCloud OpenFeign + Nacos正确打开方式!


d878838501bfe954bc00aea2966644b0.png

SpringCloud Ribbon中的7种负载均衡策略!


1477e440409431e2cfa754cfea99b954.png

SpringCloud Nacos + Ribbon 调用服务的 2 种方法!


14043c883d5cfc06c0b578479391898a.gif

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

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

相关文章

java的equals方法_Java Vector equals()方法与示例

java的equals方法向量类的equals()方法 (Vector Class equals() method) equals() method is available in java.util package. equals()方法在java.util包中可用。 equals() method is used to check whether this Vector is the same or equals to the given object (ob) or …

推荐几个好文章

1 cocos2dx各种行动 http://www.cnblogs.com/linux-ios/archive/2013/04/06/3001946.html 2 cocos2dx自己定义曲线 http://blog.csdn.net/ufolr/article/details/7447773 3 lua中载入cocostudio动画&#xff0c;触发帧事件&#xff08;非常全&#xff0c;非常具体。还有源代码…

treeset java_Java TreeSet first()方法与示例

treeset javaTreeSet类的first()方法 (TreeSet Class first() method) first() method is available in java.util package. first()方法在java.util包中可用。 first() method is used to retrieve the first lowest element in this TreeSet. first()方法用于检索此TreeSet中…

Java常用类:7000字一次性帮你总结好啦!

来源&#xff1a;cnblogs.com/lwtyyds/p/15678152.html常用类概述内部类内部类的分类&#xff1a;1.成员内部类&#xff08;非静态内部类&#xff09;2.局部内部类4.匿名内部类Object类Object类常用方法&#xff1a;1.equals方法2.hashCode方法3.toString方法4.finzlize方法包装…

CentOS6.4系统启动失败故障排查

转&#xff1a;http://www.centoscn.com/CentosBug/osbug/2014/1028/4011.html 操作系统启动失败如下图报错&#xff1a; 故障现象&#xff1a; 从图中可以看到&#xff0c;操作系统启动的过程中&#xff0c;fsck在执行文件系统检测时出现了错误&#xff0c;并且是在检查/dev/m…

hashmap clone_Java HashMap clone()方法与示例

hashmap cloneHashMap类clone()方法 (HashMap Class clone() method) clone() method is available in java.util package. clone()方法在java.util包中可用。 clone() method is used to get a cloned copy of this HashMap instance or in other words, we can say it return…

Linux内存管理--物理内存分配【转】

转自&#xff1a;http://blog.csdn.net/myarrow/article/details/8682819 1. First Fit分配器 First Fit分配器是最基本的内存分配器&#xff0c;它使用bitmap而不是空闲块列表来表示内存。在bitmap中&#xff0c;如果page对应位为1&#xff0c;则表示此page已经被分配&#xf…

JDK的一个Bug,监听文件变更要小心了

背景 在某些业务场景下&#xff0c;我们需要自己实现文件内容变更监听的功能&#xff0c;比如&#xff1a;监听某个文件是否发生变更&#xff0c;当变更时重新加载文件的内容。看似比较简单的一个功能&#xff0c;但如果在某些JDK版本下&#xff0c;可能会出现意想不到的Bug。本…

hashset java_Java HashSet clear()方法与示例

hashset javaHashSet类的clear()方法 (HashSet Class clear() method) clear() method is available in java.util package. clear()方法在java.util包中可用。 clear() method is used to clear all of the element exists from this HashSet. clear()方法用于清除此HashSet中…

推荐 17 个压箱底的常用类库

前言在java的庞大体系中&#xff0c;其实有很多不错的小工具&#xff0c;也就是我们平常说的&#xff1a;轮子。如果在我们的日常工作当中&#xff0c;能够将这些轮子用户&#xff0c;再配合一下idea的快捷键&#xff0c;可以极大得提升我们的开发效率。今天我决定把一些压箱底…

02、django中的上下文

2019独角兽企业重金招聘Python工程师标准>>> 1、譬如设置网站的名称,setting中设置变量&#xff1a; # setting.py SITE_NAME "我的小站"2、在view中写函数将该变量转换成字典,做返回值 from django.conf import settings def site_key(request):# 这里使…

enumset.allof_Java EnumSet allOf()方法与示例

enumset.allofEnumSet类的allOf()方法 (EnumSet Class allOf() method) allOf() method is available in java.util package. allOf()方法在java.util包中可用。 allOf() method is used to return Enumset that has all of the elements of the given element type (ele_ty). …

实战:10 种实现延迟任务的方法,附代码!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;这篇文章的诞生要感谢一位读者&#xff0c;是他让这篇优秀的文章有了和大家见面的机会&#xff0c;重点是优秀文章&#xff…

netsh命令

C:\Windows\System32>netsh interface ipv6 show address levelverbose 地址 ::1 参数---------------------------------------------------------接口 Luid : Loopback Pseudo-Interface 1作用域 ID : 0.0有效生存时间 : infinite首选生存时间 : infiniteDAD 状态 : 首选项…

面渣逆袭:Redis连环五十二问!三万字+八十图详解!

基础1.说说什么是Redis?Redis图标Redis是一种基于键值对&#xff08;key-value&#xff09;的NoSQL数据库。比一般键值对数据库强大的地方&#xff0c;Redis中的value支持string&#xff08;字符串&#xff09;、hash&#xff08;哈希&#xff09;、 list&#xff08;列表&…

hdu 4864 Task(贪婪啊)

主题链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid4864 Task Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1346 Accepted Submission(s): 336Problem DescriptionToday the company has m ta…

svg学习网站

1、http://www.runoob.com/svg

EasyExcel太方便易用了,强烈推荐!

背景 系统中经常要导出大量的数据&#xff0c;格式基本上都是Excel&#xff0c;然而每次导表都是对系统内存的一次挑战。在Java领域&#xff0c;生成或解析Excel的框架比较有名的当属Apache的poi和jxl了。但使用它们&#xff0c;会面临着严重的内存损耗问题。如果系统的并发量还…

Java Date hashCode()方法与示例

日期类hashCode()方法 (Date Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to retrieve hash code of this Date object. hashCode()方法用于检索此Date对象的哈希码。 has…

eclispe快捷键

快捷键无效解决办法&#xff1a; 1、考虑是否被其他应用占用&#xff0c;如QQ&#xff0c;QQ音乐&#xff0c;千千动听等 2、在eclispe查看是否被修改&#xff1a;Window->Preferences->General->Keys 快捷键&#xff1a; 1、复制当前行到下一行&#xff1a;CtrlAlt↓…