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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: Spring Cloud OpenFeign 的 5 个优化小技巧!

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

## 1.超时优化

OpenFeign 底层内置了 Ribbon 框架,并且使用了 Ribbon 的请求连接超时时间和请求处理超时时间作为其超时时间,而 Ribbon 默认的请求连接超时时间和请求处理超时时间都是 1s,如下源码所示:

![image.png](https://cdn.nlark.com/yuque/0/2022/png/92791/1644979639962-f1f9a74f-cc67-41b0-9260-d765e7070c6d.png#clientId=u05db437e-8610-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=335&id=u0999be57&margin=%5Bobject%20Object%5D&name=image.png&originHeight=669&originWidth=1740&originalType=binary&ratio=1&rotation=0&showTitle=false&size=136097&status=done&style=none&taskId=u5844fb76-be36-4d36-9c3d-2b764eaf7c5&title=&width=870)

所有当我们使用 OpenFeign 调用了服务接口超过 1s,就会出现以下错误:

![image.png](https://cdn.nlark.com/yuque/0/2022/png/92791/1644937135040-13b2f803-ed86-43e5-bf3a-e6f5e69329a0.png#clientId=u489a9d70-fa17-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=441&id=u13186931&margin=%5Bobject%20Object%5D&name=image.png&originHeight=882&originWidth=2822&originalType=binary&ratio=1&rotation=0&showTitle=false&size=325710&status=done&style=none&taskId=ube782481-eede-45aa-973a-a432e0c7521&title=&width=1411)

因为 1s 确实太短了,因此我们需要手动设置 OpenFeign 的超时时间以保证它能正确的处理业务。

OpenFeign 的超时时间有以下两种更改方法:

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

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

 

  ### 1.1 设置Ribbon超时时间

 

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

 

  ```yaml

  ribbon:

  ReadTimeout: 5000 # 请求连接的超时时间

  ConnectionTimeout: 10000 # 请求处理的超时时间

  ```

 

  ### 1.2 设置OpenFeign超时时间

 

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

 

  ```yaml

  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 中添加以下配置:

 

  ```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 中添加以下配置,:

 

  ```yaml

  feign:

  client:

   httpclient: # 开启 HttpClient

     enabled: true

  ```

 

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

  ![image.png](https://cdn.nlark.com/yuque/0/2022/png/92791/1644982041712-9fa4b3a4-ae54-43a6-84d9-1aa5c3e3480f.png#clientId=u01a8181f-25b5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=406&id=uc494945e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=811&originWidth=2482&originalType=binary&ratio=1&rotation=0&showTitle=false&size=182380&status=done&style=none&taskId=u823a3570-f7a8-4975-80b6-8f04705c08c&title=&width=1241)

 

  ## 3.数据压缩

 

  OpenFeign 默认不会开启数据压缩功能,但我们可以手动的开启它的 Gzip 压缩功能,这样可以极大的提高宽带利用率和加速数据的传输速度,在项目配置文件 application.yml 中添加以下配置:

 

  ```yaml

  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 做负载均衡的,查看源码我们可以看到它默认的负载均衡策略是轮询策略,如下图所示:

![image.png](https://cdn.nlark.com/yuque/0/2022/png/92791/1644978284287-212a3d9d-e053-478c-a1b1-4ae8e9fd866d.png#clientId=uca1d3035-f455-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=421&id=aRewN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=842&originWidth=2701&originalType=binary&ratio=1&rotation=0&showTitle=false&size=195374&status=done&style=none&taskId=ucdd2b71e-2998-4dd2-b1a5-43be808acdf&title=&width=1350.5)

然而除了轮询策略之外,我们还有其他 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 中定义的信息之外,还有请求和响应的正文及元数据。

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

```yaml

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](https://gitee.com/mydb/interview)

相关文章
|
11天前
|
缓存 监控 Java
《深入理解Spring》性能监控与优化——构建高性能应用的艺术
本文系统介绍了Spring生态下的性能监控与优化实践,涵盖监控体系构建、数据库调优、缓存策略、线程池配置及性能测试等内容,强调通过数据驱动、分层优化和持续迭代提升应用性能。
|
20天前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
81 8
|
1月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
354 4
|
6月前
|
前端开发 Java UED
从基础到进阶:Spring Boot + Thymeleaf 整合开发中的常见坑与界面优化
本文深入探讨了 **Spring Boot + Thymeleaf** 开发中常见的参数绑定问题与界面优化技巧。从基础的 Spring MVC 请求参数绑定机制出发,分析了 `MissingServletRequestParameterException` 的成因及解决方法,例如确保前后端参数名、类型一致,正确设置请求方式(GET/POST)。同时,通过实际案例展示了如何优化支付页面的视觉效果,借助简单的 CSS 样式提升用户体验。最后,提供了官方文档等学习资源,帮助开发者更高效地掌握相关技能。无论是初学者还是进阶用户,都能从中受益,轻松应对项目开发中的挑战。
288 0
|
6月前
|
存储 Java 数据库
Spring Boot 注册登录系统:问题总结与优化实践
在Spring Boot开发中,注册登录模块常面临数据库设计、密码加密、权限配置及用户体验等问题。本文以便利店销售系统为例,详细解析四大类问题:数据库字段约束(如默认值缺失)、密码加密(明文存储风险)、Spring Security配置(路径权限不当)以及表单交互(数据丢失与提示不足)。通过优化数据库结构、引入BCrypt加密、完善安全配置和改进用户交互,提供了一套全面的解决方案,助力开发者构建更 robust 的系统。
193 0
|
6月前
|
Java 开发者 微服务
Spring Cloud OpenFeign详解与实践
总结起来说,Spring Cloud OpenFeign提供了一种简单易懂且高效的方式去实现微服务之间通信.它隐藏了许多复杂性,并且允许开发者以声明式方式编写HTTP客户端代码.如果你正在开发基于Spring Cloud 的微服务架构系统,Spring Cloud Open Feign是一个非常好用且强大工具.
445 33
|
10月前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
835 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
10月前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
161 6
|
10月前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
178 5
|
10月前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
199 5

热门文章

最新文章