谈谈Spring Cloud OpenFeign远程调用性能优化

Java
408
0
0
2023-05-26
标签   SpringCloud

前沿

本文主要是分享一下 OpenFeign 几个方面优化的小技巧,主要分为以下几点:

  • 请求通讯连接优化
  • 超时优化
  • 负载均衡
  • 数据压缩
  • 日志级别优化

一、请求通讯连接优化

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

1.1 添加 pom 依赖

 <!-- 添加 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> 

1.2 开启Apache HttpClient使用

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

 spring:
  cloud:
    feign:
      client:
        httpclient:
          # 默认Feign使用的是JDK自带的URLConnection进行Http请求的,手动替换成Apache HttpClient专用的通信组件
          enabled: true    

验证 Apache HttpClient 配置是否生效,通过debug调试,在 feign.SynchronousMethodHandler#executeAnd Decode () 方法上打端断点,通过发起一个远程调用请求,在没配置替换前,是这样的:

配置替换后,可以看看默认使用的client是已经被替换成Apache HttpClient:

二、Ribbon超时优化

OpenFeign Feign 底层都内置了 Ribbon 负载均衡组件,在导入 OpenFeign 依赖后无需专门导入 Ribbon 依赖。 OpenFeign 也因此使用了 Ribbon 的请求连接超时时间和请求处理超时时间作为其超时时间,而 Ribbon 默认的请求连接超时时间和请求处理超时时间都是1s,如下源码所示:

所以我们使用OpenFeign远程调用微服务接口响应时间超过1s时,就会出以下报错:

2.1 设置OpenFeign调用超时时间

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

 # 远程调用优化
feign:
  client:
    httpclient:
      # 默认Feign使用的是JDK自带的URLConnection进行Http请求的,手动替换成Apache HttpClient专用的通信组件
      enabled: true
     config :
      default: # 设置的全局超时时间
        connectTimeout: 3000 # 请求连接的超时时间
        readTimeout: 5000 # 请求处理的超时时间 

2.2 设置Ribbon超时时间

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

通过debug的方式验证以下设置的超时时间是否生效,很明显配置已经生效,主要看 org.springframework.cloud.openfeign.FeignClientFactoryBean#configureUsingProperties() 方法,源码如下图所示:

再次调用发现已经不会再报请求超时的异常了!

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

三、数据压缩

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  # 开启响应数据压缩功能 
Tip提醒: 如果服务消费端的 CPU 资源比较紧张的话, 建议不要开启数据的压缩功能 ,因为数据压缩和解压都需要消耗CPU的资源,这样反而会给CPU增加了额外的负担,也会导致系统性能降低。

四、负载均衡优化

OpenFeign 底层使用的是 Ribbon 做负载均衡的,查看源码我们可以看到它默认的负载均衡策略是 轮询 策略,源码位置: com.netflix.loadbalancer.BaseLoadBalancer ,如下图所示:

然而除了轮询策略之外,我们还有其他6种内置的负载均衡策略可以选择,这些负载均衡策略如下:

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

五、OpenFeign调用日志级别优化

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

  • NONE【性能最佳,适用于生产】: 默认的,不显示任何日志。
  • BASIC 【适用于生产环境追踪问题】: 仅记录请求方法、URL、响应状态码及执行时间。
  • HEADERS【适用于需查看请求头信息】: 除了 BASIC 中定义的信息之外,还有请求和响应的头信息。
  • FULL【比较适用于开发级 测试环境 定位问题】: 除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

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

 logging:
  level:
    com.jacklin.mamba.contentcenter.post.feignClient.UserCenterFeignClient: debug # feign的自定义接口
 

六、总结

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

  1. 修改 OpenFeign 的超时时间,让 OpenFeign 能够正确的处理业务;
  2. 通过配置专用的通信组件 Apache HttpClient OKHttp ,让 OpenFeign 可以通过 线程池 更好地对 HTTP 连接对象进行重用和管理,以提高其性能;
  3. 开启数据压缩功能,可以提高宽带利用率和加速数据传输速度;
  4. 使用合适的负载均衡策略来替换默认的轮询负载均衡策略,已获得更好的执行效率;
  5. 检查生成环境中 OpenFeign 的日志级别,选择合适的日志输出级别,防止无效的日志输出。