Feign原理以及feign调优

Feign原理以及feign调优

1. Feign原理

Feign是一个轻量级的HTTP客户端库,它可以用来进行RESTful API的调用。在Feign中,你只需要定义一个接口,然后就可以使用这个接口来进行HTTP请求。这种方式可以让我们的代码更加简洁和易于维护。

  1. Feign的核心接口是feign.Client,它定义了发送HTTP请求的方法。具体来说,这个接口定义了一个execute方法,它接受一个Request对象作为参数,然后返回一个Response对象。这个execute方法会根据Request对象的内容发送HTTP请求,然后返回服务器的响应。Feign中支持多种HTTP客户端,具体实现都是基于这个Client接口的。

  1. Feign的请求接口定义是通过Java接口的方式实现的。在接口中,我们可以使用@RequestLine、@Headers、@Param等注解来定义HTTP请求。例如:

@RequestLine("GET /users/{id}")
@Headers("Authorization: Basic {auth}")
User getUser(@Param("id") String id, @Param("auth") String auth);

这个接口定义了一个GET请求,请求的URL是/users/{id},其中{id}是一个参数。这个接口还定义了一个Authorization的请求头部信息,值为Basic {auth},其中{auth}是另外一个参数。这个接口会返回一个User对象。

  1. Feign的核心类是feign.ReflectiveFeign,它通过Java反射的方式将接口转换为一个HTTP请求。具体来说,它会解析接口定义中的注解,然后将这些注解转换为一个HTTP请求。这个类还支持将HTTP响应转换为接口定义中定义的返回值。这个转换过程是通过使用feign.codec.Decoder和feign.codec.Encoder这两个接口实现的。

  1. Feign的请求处理过程可以分为三个步骤:

解析接口定义,生成一个HTTP请求。在这个过程中,ReflectiveFeign会根据接口定义中的注解生成一个Request对象,然后将这个Request对象交给Client发送HTTP请求。

发送HTTP请求,获取服务器返回的响应。在这个过程中,Client会根据Request对象中的内容发送HTTP请求,然后返回服务器的响应。这个响应会包含HTTP状态码、HTTP头部信息和响应体等内容。

将服务器返回的响应转换为接口定义中定义的返回值。在这个过程中,ReflectiveFeign会根据接口定义中定义的返回值类型,使用Decoder将HTTP响应体转换为一个Java对象。然后将这个Java对象作为接口方法的返回值。

  1. Feign还支持拦截器,可以在发送HTTP请求前或者处理服务器响应后对请求和响应进行处理。这个功能可以用来实现一些通用的处理逻辑,例如添加统一的请求头部信息、记录日志等。具体来说,Feign中的拦截器是通过实现feign.RequestInterceptor和feign.ResponseInterceptor这两个接口实现

  1. 在Feign的请求处理过程中,还有一个重要的组件是feign.Contract。它用于解析Feign接口上的注解并生成对应的请求元数据。默认情况下,Feign使用的是feign.Contract.Default实现,它支持@RequestLine、@Headers、@Param、@QueryMap等注解。

  1. Feign还支持负载均衡和服务发现,可以让我们更加方便地处理多个服务实例之间的负载均衡。Feign提供了一个名为feign.ribbon.RibbonClient的客户端,可以通过它来实现负载均衡。这个客户端是基于Netflix的Ribbon实现的。

  1. 最后,Feign的一些核心组件的实现类如下:

  • feign.okhttp.OkHttpClient:基于OkHttp实现的HTTP客户端。

  • feign.jaxrs.JAXRSContract:支持JAX-RS注解的Feign Contract实现。

  • feign.jackson.JacksonDecoder和feign.jackson.JacksonEncoder:使用Jackson库实现的Decoder和Encoder,用于将Java对象和JSON之间进行转换。

  • feign.ribbon.RibbonClient:基于Netflix的Ribbon实现的客户端,支持负载均衡和服务发现。

2. feign优化

2.1. 开启feign日志

feign:
  client:
     config:
         #feign-provider:
          default:
            loggerLevel: full #开启feign日志
logging:
  level:
    com.bjpowernode.feign: debug #log4j的日志级别

在应用程序中启用Feign客户端的日志记录功能后,Feign将会记录以下信息:

  1. 请求/响应头信息:请求/响应的HTTP头信息将被记录下来,包括请求方法、请求路径、请求头、响应码等等。

  1. 请求/响应体信息:如果请求或响应包含消息体(如JSON或XML),Feign将记录它们。

  1. 错误信息:如果请求返回了错误响应,Feign将记录错误信息,包括响应码和错误消息。

以下是一个示例Feign日志记录:

2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> POST http://example.com/api/login HTTP/1.1
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Content-Type: application/json;charset=UTF-8
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Accept: application/json;charset=UTF-8
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Content-Length: 37
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> {"username":"johndoe","password":"secret"}
2022-03-16 08:23:45.456 DEBUG [feign.Logger$Default] <-- 200 OK http://example.com/api/login (333ms)
2022-03-16 08:23:45.456 DEBUG [feign.Logger$Default] <-- Content-Type: application/json;charset=UTF-8
2022-03-16 08:23:45.456 DEBUG [feign.Logger$Default] <-- Content-Length: 123
2022-03-16 08:23:45.456 DEBUG [feign.Logger$Default] <-- {"access_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzkwMjJ9.TpZ7SK4CE92GMYRUkgF2fswd4yJUG-wXl3qHZ32aWe8","token_type":"Bearer","expires_in":3600}

在此示例中,Feign记录了一个POST请求,包括请求头、请求体、响应头和响应体信息。请求返回了200 OK响应,并包含一个JSON格式的响应体。

除了上面提到的基本信息,Feign还可以记录其他有用的信息,例如重试次数、请求/响应时间、连接池状态等。以下是Feign日志中可能包含的其他信息:

  1. 重试次数:如果启用了Feign的重试功能,并且请求失败后进行了重试,Feign将记录重试次数。

  1. 请求/响应时间:Feign将记录请求和响应的时间戳,并计算请求/响应时间。这可以帮助您分析性能问题。

  1. 连接池状态:如果您的应用程序使用连接池来管理HTTP连接,Feign将记录连接池中连接的状态,例如空闲连接数、活动连接数等。

以下是一个包含所有这些信息的示例Feign日志记录:

2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> POST http://example.com/api/login HTTP/1.1
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Content-Type: application/json;charset=UTF-8
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Accept: application/json;charset=UTF-8
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> Content-Length: 37
2022-03-16 08:23:45.123 DEBUG [feign.Logger$Default] --> {"username":"johndoe","password":"secret"}
2022-03-16 08:23:45.456 DEBUG [feign.Logger$Default] [RetryableFeignLoadBalancer] [c7e21e95-2cf7-4b49-890f-9d0b8ec79f1a] [GET] [example.com] is alive
2022-03-16 08:23:45.789 DEBUG [feign.Logger$Default] [RetryableFeignLoadBalancer] [c7e21e95-2cf7-4b49-890f-9d0b8ec79f1a] [GET] [example.com] requesting to GET http://example.com/api/user/123
2022-03-16 08:23:46.012 DEBUG [feign.Logger$Default] [RetryableFeignLoadBalancer] [c7e21e95-2cf7-4b49-890f-9d0b8ec79f1a] [GET] [example.com] [Response received in 223ms] [Retry#1]
2022-03-16 08:23:46.456 DEBUG [feign.Logger$Default] <-- 200 OK http://example.com/api/login (333ms)
2022-03

2.2. 开启GZIP压缩

GZIP是一种数据压缩算法,可以将数据压缩为更小的大小,从而节省网络带宽和存储空间。它是一种无损压缩算法,可以在不丢失数据的情况下压缩数据。以下是GZIP压缩的一些详细说明:

  1. 压缩原理:GZIP压缩算法采用LZ77算法和霍夫曼编码进行压缩。LZ77算法使用重复的数据块来减小数据的大小,而霍夫曼编码将最频繁出现的数据编码成较短的码字,从而减小数据的大小。

  1. 压缩效率:GZIP压缩算法可以将数据压缩为原始数据的40%~60%左右。这意味着在传输数据时,使用GZIP可以显著减少传输的数据量,从而减少网络带宽的使用。

  1. 压缩格式:GZIP压缩算法生成的压缩数据是一种二进制格式,通常包含文件头和文件尾。文件头包含一些元数据,例如压缩方法、时间戳、操作系统类型等,而文件尾包含一些校验和信息,用于检测数据是否完整。

  1. 解压缩:解压缩GZIP数据很容易。大多数操作系统都提供了GZIP的解压缩工具,例如Linux中的gunzip命令和Windows中的WinZip工具。您也可以在Java中使用java.util.zip包提供的GZIPInputStream和GZIPOutputStream类进行压缩和解压缩。

  1. 应用场景:GZIP压缩算法通常用于Web应用程序中,以减少HTTP请求和响应的数据量。例如,Web服务器可以将静态资源(例如HTML、CSS、JavaScript文件)进行GZIP压缩,并在HTTP响应中设置Content-Encoding头以指示数据已经被压缩。Web浏览器将自动解压缩数据并显示页面内容。这可以显著减少页面加载时间和网络带宽的使用。

server:
  compression:
     enabled: true #开启浏览器<----->consumer的gzip压缩

 feign:
   ompression: #开启feign<----->provider的gzip压缩
      request:
         enabled: true
      response:
         enabled: true

2.3. 开启Http 连接池

HTTP连接池是一种管理HTTP连接的技术,它可以在多个HTTP请求之间共享和重用连接,以提高HTTP请求的性能和效率。以下是HTTP连接池的一些详细说明:

  1. 连接池原理:HTTP连接池将多个HTTP连接放入连接池中,并在需要时从池中获取连接来处理HTTP请求。当请求完成后,连接将被放回连接池中以供重用。通过重用连接,连接池可以避免创建和关闭连接的开销,从而提高HTTP请求的性能和效率。

  1. 连接池大小:连接池的大小是连接池性能和效率的重要因素之一。连接池的大小应该根据系统负载和网络带宽进行调整。如果连接池太小,HTTP请求可能会等待可用连接,从而影响性能。如果连接池太大,会占用过多的内存和CPU资源,从而影响效率。

  1. 连接超时:连接池应该具有连接超时功能。当连接在指定的时间内无法建立时,连接池应该抛出异常并释放连接资源。这可以避免因连接问题而导致HTTP请求超时的问题。

  1. 连接空闲超时:连接池应该具有连接空闲超时功能。当连接在指定的时间内未被使用时,连接池应该关闭连接并释放连接资源。这可以避免连接资源浪费和系统负载的问题。

  1. 连接重用:连接池应该尽可能地重用连接,以减少创建和关闭连接的开销。连接池应该确保连接的状态是正确的,例如连接是否被关闭、是否存在未读取的数据等。

  1. 线程安全:连接池应该是线程安全的。多个线程可以同时从连接池中获取连接,并使用连接来处理HTTP请求。连接池应该确保在多线程环境中正确地管理连接资源。

  1. 实现方式:连接池可以使用Java中的Apache HttpClient或Java HttpClient等第三方库来实现。这些库提供了可配置的连接池,可以根据应用程序的需要进行调整。

HTTP连接池可以在大多数Web应用程序中提高性能和效率。它可以避免频繁创建和关闭连接的开销,从而提高HTTP请求的性能。

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

2.4. 设置feign超时

在使用Feign进行HTTP请求时,由于网络延迟或服务器处理时间过长等原因,可能会导致请求超时。Feign提供了一些配置选项,可以用于设置请求超时时间,以便在请求超时时进行适当的处理。

方式一:

ribbon:
   ConectionTimeout: 5000 #请求连接的超时时间
   ReadTimeout: 5000 #请求响应的超时时间

方式二:

feign:
  client:
     config:
        #feign-provider:
        default:
           onectionTimeout: 5000 #请求连接的超时时间
           ReadTimeout: 5000 #请求响应的超时时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Cloud Feign是一个基于Netflix Feign的声明式Web服务客户端,它使得编写Web服务客户端变得更加简单。它通过注解的方式来定义和配置Web服务接口,使得开发者只需要关注业务逻辑的实现,而无需关注底层的实现细节。在运行时,Feign会根据注解信息自动创建出具体的Web服务客户端,并且将请求转发到指定的Web服务端点。同时,Feign还提供了负载均衡、熔断器等功能,可以帮助开发者构建高可用、高可靠的Web服务应用。 ### 回答2: Spring Cloud Feign是一个基于Spring Cloud的声明式REST客户端,可以让开发者更加便捷地进行微服务间的通信。其原理可以简单地概括为:通过注解定义服务接口,Feign根据注解生成服务代理对象,调用服务时候,Feign将请求参数编码成HTTP请求并发送请求到服务提供方,接收到服务提供方的响应后,将响应解码成返回对象并返回给调用方。 在实现原理上,Spring Cloud Feign主要依赖于以下三种技术: 1.动态代理技术:Feign使用Java动态代理技术,在运行时生成服务接口的实现类,并将服务接口方法映射到HTTP请求中,实现了将服务接口映射到HTTP请求的自动化。 2.Ribbon和Eureka或Consul:Feign利用Ribbon和Eureka或Consul两个组件实现了负载均衡和服务发现。在服务消费方和服务提供方之间建立连接时,使用Ribbon对服务提供方进行负载均衡,加上Eureka或Consul的服务发现机制,使得分布式系统之间的通信变得更加稳定和可靠。 3.编解码技术:Feign使用编解码技术将请求参数和响应抽象为Java对象,并使用Jackson实现JSON序列化和反序列化,实现了请求参数的传输和响应结果的解析。 总之,Spring Cloud Feign使得微服务之间的通信更加便捷、高效、可靠,为微服务架构的开发提供了有效的解决方案。 ### 回答3: Spring Cloud Feign是一种基于Spring Cloud的轻量级原型客户端,它使用了注解的方式来定义和实现RESTful服务的客户端,并且不需要额外的代码来实现远程调用,只需要使用接口来定义相应的服务,Feign会自动帮我们实现相应的调用请求。 Spring Cloud Feign的实现原理包括以下几个方面: 1. 接口代理 在使用Spring Cloud Feign时,我们只需要定义一个接口,然后在接口上添加相应的注解,就可以轻松地实现远程服务的调用。这是因为在使用Feign时,Feign会根据接口定义生成一个代理对象,在运行时使用代理对象来调用远程服务。 2.注解解析器 Spring Cloud Feign主要通过注解的方式来定义RESTful服务,它会解析这些注解来生成相应的HTTP请求。通过使用注解,我们可以定义URL、HTTP请求方法、请求头信息、请求参数等,灵活地满足我们对于远程服务的调用需求。 3.集成了Ribbon负载均衡 Spring Cloud Feign在进行远程调用时,还会集成Ribbon负载均衡机制。Ribbon是Netflix开源的一款负载均衡框架,它通过在客户端侧配置算法来均衡负载,可以使得服务调用更加稳定和高效。 4.优秀的可扩展性 Spring Cloud Feign提供了出色的可扩展性,我们可以通过自定义注解解析器来扩展Feign的功能。同时,Feign还支持自定义编码器、解码器、日志记录器等,可以支持更复杂、更个性化的远程服务调用需求。 总之,Spring Cloud Feign是一种优秀的远程服务调用工具,它使用注解来定义RESTful服务并自动生成代理对象实现调用,同时还集成了Ribbon负载均衡机制,可扩展性强,非常适合用于微服务架构下的远程服务调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值