当前位置:首页 > 技术分析 > 正文内容

微服务系列:服务调用 Spring Cloud 之 OpenFeign 性能优化

ruisui883个月前 (02-03)技术分析19

今天,我们来学习一下 OpenFeign 性能优化的相关配置。

话不多说,开始今天的学习。

日志增强

浏览器发起的请求可以通过F12查看请求和响应信息。如果想看微服务中每个接口我们可以使用日志配置方式进行查看详细信息。

OpenFeign 虽然提供了日志增强功能,但是默认是不显示任何日志的,不过开发者在调试阶段可以自己配置日志的级别。

OpenFeign 的日志级别如下:

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
  • FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

配置如下:

1. 设置接口日志级别

application.yml 文件中

logging:
  level:
    com.ezhang.auth.service: debug

com.ezhang.auth.service: debug 是接口所在的包名

当然设置日志级别使用配置文件 logback.xml 设置也是一样的。

注:

关于 Spring Boot Logging 配置贴一篇其他大佬的文章详解 Spring Boot Logging 配置

2. 配置类中配置 OpenFeign 日志级别

自定义一个配置类,在其中设置日志级别,这样是全局的配置

@Configuration
public class FeignConfiguration {
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

局部配置,在客户端接口指定此配置

configuration = FeignConfiguration.class

@FeignClient(contextId = "remoteUserService", value = "cloud-system", fallbackFactory = RemoteUserFallbackFactory.class, configuration = FeignConfiguration.class)
public interface RemoteUserService {

    @GetMapping(value = "/user/getUserInfo")
    Map<String, Object> getUserInfo(@RequestParam("userId") int userId);

}

3. 效果

发送请求 http://localhost:9203/test/getUserInfo?userId=2,控制台上就可以看到详细的请求信息啦。

GZIP 压缩

介绍

gzip 是一种数据格式,采用用 deflate 算法压缩 data;gzip 是一种流行的文件 压缩算法,应用十分广泛,尤其是在 Linux 平台。

能力

当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减少 70% 以上的文件大小。

作用

网络数据经过压缩后实际上降低了网络传输的字节数,最明显的好处就是可 以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏 览体验外,另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。例如 Google 就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。

OpenFeign 开启 GZIP 步骤:

1. 项目中启用 gzip 压缩

server:
  port: 9203
  # 是否开启压缩
  compression:
    enabled: true
    # 配置支持压缩的 MINE TYPE
    mime-types: text/html,text/xml,text/plain,application/xml,application/json

2. 在 Feign 服务提供方开启 gzip 压缩

feign:
  compression:
    request:
      # 开启请求压缩
      enabled: true
      # 配置支持压缩的 MINE TYPE
      mime-types: text/xml,application/xml,application/json
      # 配置压缩数据大小的下限
      min-request-size: 2048
    response:
      # 开启响应压缩
      enabled: true

3. 效果

上述配置完成后,发起请求,观察控制台日志:

Http 连接池

两台服务器建立HTTP连接的过程涉及到多个数据包的交换,很消耗时间。采用HTTP连接池可以节约大量的时间提示吞吐量。

Feign的HTTP客户端支持3种框架:HttpURLConnection、HttpClient、OkHttp。

观察源码可以发现,Feign 默认是采用java.net.HttpURLConnection 的,每次请求都会建立、关闭连接。

首先查看 FeignRibbonClient 的自动配置类 FeignRibbonClientAutoConfiguration,该类在程序启动的时候注入一些 Bean,其中注入了一个 BeanName 为 feignClient 的 Client 类型的 Bean。在省缺配置 BeanName 为 FeignClient 的 Bean 的情况下,会自动注入 Client.Default 这个对象,跟踪Client.Default 源码, Client.Default 使用的网络请求框架是 HttpURLConnection,代码如下:

public static class Default implements Client {
    private final SSLSocketFactory sslContextFactory;
    private final HostnameVerifier hostnameVerifier;
    private final boolean disableRequestBuffering;
    
    public Response execute(Request request, Options options) throws IOException {
        HttpURLConnection connection = this.convertAndSend(request, options);
        return this.convertResponse(connection, request);
    }
    // 省略其他源码
}

为了性能考虑,我们可以引入httpclient、okhttp作为底层的通信框架。

例如将 Feign 的 HTTP 客户端工具修改为 HttpClient。

1. 添加依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

2. 配置文件中开启

feign:
  # 开启 httpclient
  httpclient:
    enabled: true

3. 如何验证

在feign.SynchronousMethodHandler#executeAndDecode()这个方法中可以清楚的看出调用哪个 client。

在未替换 httpclient 之前,是这样的:

替换成功之后是这样的:

4. 源码分析

我们来查看下 HttpClientFeignLoadBalancedConfiguration 的源码:

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({ApacheHttpClient.class})
@ConditionalOnProperty(
    value = {"feign.httpclient.enabled"},
    matchIfMissing = true
)
@Import({HttpClientFeignConfiguration.class})
class HttpClientFeignLoadBalancedConfiguration {
    HttpClientFeignLoadBalancedConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean({Client.class})
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory, HttpClient httpClient) {
        ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
        return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
    }
}

从 @ConditionalOnProperty 注解可知,配置文件中开启 httpclient 可以不写,因为在默认情况下就为true。

@Import({HttpClientFeignConfiguration.class}) HttpClientFeignConfiguration 这个配置类感兴趣的小伙伴可以自己看看。

熔断降级

常见的熔断降级框架有Hystrix、Sentinel,openFeign默认支持的就是Hystrix。

其实在上一篇文章中已经有了熔断降级的实现 微服务系列:服务调用 Spring Cloud 之 OpenFeign 详细入门

fallbackFactory = RemoteUserFallbackFactory.class

这里就不再赘述了。包括可以换成集成 Sentinel 来实现熔断降级。

其实不管是Hystrix还是Sentinel对于Feign的支持,核心代码基本上是一致的,只需要修改依赖和配置文件即可。

其他

除了上面这些优化之外,还有个没有写,就是 请求超时配置,这个准备再整一篇文章写一写。因为感觉小篇幅还搞不定。。。

feign 可以设置请求超时时间,ribbon 可以设置,hystrix 也可以设置。

如何统筹考虑 ribbon、feign、hystrix 三者之间的关系,添加合适的配置,使得各个组件各司其职、协调合作, 是一个麻烦的问题。

想想就令人头秃。

PS: 都看到这里了,点个赞吧,彦祖!

作者:程序猿秃头之路
链接:https://juejin.cn/post/7055863611029192740

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1189.html

标签: feign 使用
分享给朋友:

“微服务系列:服务调用 Spring Cloud 之 OpenFeign 性能优化” 的相关文章

30 个纯 HTML5 实现的游戏

浏览器和 JavaScript 的功能逐年不断的变强变大。曾几何时,任何类型的游戏都需要Flash。但随着 HTML5 发展,HTML5 + WebGL 游戏式就慢慢占领着这个舞台。以下是30款流行的游戏,它们可以在所有现代浏览器中运行,并且只使用web技术构建。1. HexGL地址:http://...

vue v-html动态生成的html怎么加样式/事件

1、动态生成的html,样式不生效//html 布局 <view v-html="html"> {{html}} </view> //动态生成的元素 <view class="btngo" @tap="handleLink...

vue3使用vue-router路由(路由懒加载、路由传参)

vue-router 是 vue的一个插件库1. 专门用来实现一个SPA单页面应用2 .基于vue的项目基本都会用到此库SPA的理解1) 单页Web应用(single page web application,SPA)2) 整个应用只有一个完整的页面3) 点击页面中的链接不会刷新页面, 本身也不会向...

三、Uni-app + vue3 页面如何跳转及传参?

Vue 项目往往需要使用 vue-router 插件,刚开始入门 Uni-app + Vue3 项目的同学,会不会想着路由使用 vue-router V4 版本不就可以了吗?不怕大家笑话,我就是这样想的,毕竟我是第一次使用 Uni-app ,由于孕期记性贼差,所以我决定写成笔记,加深记忆。uni-a...

Vue学习笔记之动态路由的参数传递应用及技巧

路由的参数传递:①通过params的类型· 配置路由格式:/router/:id· 传递的方式:在path后面跟上对应的值· 传递后形成的路径:/router/list,/router/profile这个就是前两篇中提到的"动态路由"中有应用过这个方法:②通过query的类型(对象方...

vue 开发规范

项目运行指南(#项目运行指南)开发本地环境(#开发本地环境)开发相关插件/工具(#开发相关插件工具)开发规范(#开发规范)vue(#vue)【数据流向】(#数据流向)【慎用全局注册】(#慎用全局注册)【组件名称】(#组件名称)【组件中的 CSS】(#组件中的-css)【统一标签顺序】(#统一标签顺序...