【openfeign】OpenFeign的扩展、日志、超时时间、拦截器、客户端组件、压缩

这篇具有很好参考价值的文章主要介绍了【openfeign】OpenFeign的扩展、日志、超时时间、拦截器、客户端组件、压缩。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Feign的日志配置

有时候我们遇到Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置Feign的日志了,以此让Feign把请求信息输出来。

全局配置

定义一个配置类,指定日志级别:

package com.morris.user.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置@Configuration
@Configuration
public class FeignConfig {

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

通过源码可以看到日志等级有4种,分别是:

  • NONE:不记录任何日志(默认值),性能最佳,适用于生产
  • BASIC:仅记录请求方法、URL、响应状态代码以及执行时间,适用于生产环境追踪问题
  • HEADERS:在BASIC级别的基础上,记录请求和响应的header
  • FULL:记录请求和响应的header、body和元数据,比较适用于开发及测试环境定位问题

上面只是指定日志的内容,还需要在配置文件中配置Client的日志级别才能正常输出日志,格式是"logging.level.feign接口包路径=debug":

logging:
  level:
    com.morris.user.client.OrderClient: debug

会看到如下的打印日志:

2023-08-14 13:53:42.948 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] ---> GET http://order-service/order/findOrderByUserId?userId=1 HTTP/1.1
2023-08-14 13:53:42.948 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] ---> END HTTP (0-byte body)
2023-08-14 13:53:43.169 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] <--- HTTP/1.1 200 (213ms)
2023-08-14 13:53:43.170 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] connection: keep-alive
2023-08-14 13:53:43.170 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] content-type: application/json
2023-08-14 13:53:43.170 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] date: Mon, 14 Aug 2023 05:53:43 GMT
2023-08-14 13:53:43.170 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] keep-alive: timeout=60
2023-08-14 13:53:43.170 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] transfer-encoding: chunked
2023-08-14 13:53:43.171 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] 
2023-08-14 13:53:43.171 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] [{"id":1,"userId":1,"goodName":"Iphone 13","price":9999}]
2023-08-14 13:53:43.171 DEBUG 22948 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#findOrderByUserId] <--- END HTTP (57-byte body)

局部配置

局部配置可以让指定调用的微服务生效,在@FeignClient注解中指定使用的配置类

package com.morris.user.client;

import com.morris.user.config.FeignConfig;
import com.morris.user.entity.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient(value = "order-service", path = "/order", configuration = FeignConfig.class)
public interface OrderClient {

    @GetMapping("findOrderByUserId")
    List<Order> findOrderByUserId(@RequestParam("userId") Long userId);

}

注意FeignConfig类不要加@Configuration注解,否则就会被Spring扫描到,变成了一个全局的配置。

同样需要在配置文件中指定日志的级别才会打印:

logging:
  level:
    com.morris.user.client.OrderClient: debug

局部配置可以在yml中配置,对应属性配置类: org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration

feign:
  client:
    config:
      order-service:  #对应微服务
        loggerLevel: FULL

拦截器

每次Feign发起http调用之前,会去执行拦截器中的逻辑,拦截器可以修改请求的参数或者头部信息。

例如我们可以在拦截器中对请求头增加认证信息,增加链路追踪信息。

下面通过拦截器在请求头中增加一个参数实现分布式系统中请求的链路追踪,自定义拦截器需要实现RequestInterceptor接口:

package com.morris.user.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;

import java.util.UUID;

public class FeignTraceRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        // 业务逻辑
        String traceId = UUID.randomUUID().toString();
        template.header("TID", traceId);
    }
}

全局配置

与日志的全局配置一样,放入到一个配置文件中。

package com.morris.user.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置@Configuration
@Configuration
public class FeignConfig {

    @Bean
    public FeignTraceRequestInterceptor feignTraceRequestInterceptor() {
        return new FeignTraceRequestInterceptor();
    }
}

局部配置

在@FeignClient注解中指定配置文件,注意FeignConfig类不要加@Configuration注解,否则就会被Spring扫描到,变成了一个全局的配置。

@FeignClient(value = "order-service", path = "/order", configuration = FeignConfig.class)

也可以在yml中配置:

feign:
  client:
    config:
      order-service:  #对应微服务
        requestInterceptors[0]: #配置拦截器
          com.morris.user.config.FeignTraceRequestInterceptor

order-service端可以通过@RequestHeader获取请求参数,建议在Filter,Interceptor中统一处理。

超时时间配置

通过Options可以配置连接超时时间和读取超时时间,Options的第一个参数是连接的超时时间(ms),默认值是 2s;第二个是请求处理的超时时间(ms),默认值是5s。

全局配置

与日志、拦截器的全局配置一样,放入到一个配置文件中。

package com.morris.user.config;

import feign.Logger;
import feign.Request;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置@Configuration
@Configuration
public class FeignConfig {

    @Bean
    public Request.Options options() {
        return new Request.Options(5000, 10000);
    }
}

超时了会抛出SocketTimeoutException异常:

2023-08-15 09:45:53.595 ERROR 11104 --- [nio-8030-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: Read timed out executing GET http://order-service/order/findOrderByUserId] with root cause

java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_281]
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) ~[na:1.8.0_281]

局部配置

在@FeignClient注解中指定配置文件,注意FeignConfig类不要加@Configuration注解,否则就会被Spring扫描到,变成了一个全局的配置。

@FeignClient(value = "order-service", path = "/order", configuration = FeignConfig.class)

也可以在yml中配置:

feign:
  client:
    config:
      order-service:  #对应微服务
        # 连接超时时间,默认2s
        connectTimeout: 5000
        # 请求处理超时时间,默认5s
        readTimeout: 10000

Feign的底层用的是Ribbon,但超时时间以Feign配置为准。

客户端组件配置

Feign中默认使用JDK原生的URLConnection发送HTTP请求,我们可以集成别的组件来替换掉URLConnection,比如Apache HttpClient,OkHttp。

Feign发起调用真正执行逻辑:feign.Client#execute(扩展点)

配置Apache HttpClient

引入HttpClient依赖:

<!-- Apache HttpClient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.7</version>
</dependency>
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
    <version>10.1.0</version>
</dependency>

然后修改yml配置,将Feign的Apache HttpClient启用:

feign:
  #feign 使用 Apache HttpClient  可以忽略,默认开启
  httpclient:
    enabled: true  

关于配置可参考源码:org.springframework.cloud.openfeign.FeignAutoConfiguration

测试:调用会进入feign.httpclient.ApacheHttpClient#execute

配置OkHttp

引入OkHttp的依赖:

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

然后修改yml配置,将Feign的HttpClient禁用,启用OkHttp,配置如下:

feign:
  #feign 使用 okhttp
  httpclient:
    enabled: false
  okhttp:
    enabled: true

关于配置可参考源码:org.springframework.cloud.openfeign.FeignAutoConfiguration

测试:调用会进入feign.okhttp.OkHttpClient#execute

GZIP压缩配置

开启压缩可以有效节约网络资源,提升接口性能,我们可以配置GZIP来压缩数据:

feign:
  # 配置 GZIP 来压缩数据
  compression:
    request:
      enabled: true
      # 配置压缩的类型
      mime-types: text/xml,application/xml,application/json
      # 最小压缩值
      min-request-size: 2048
    response:
      enabled: true

开启后在日志中会看到请求头中有gzip:

2023-08-15 14:38:38.482 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] ---> POST http://order-service/order/bigJson HTTP/1.1
2023-08-15 14:38:38.482 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Accept-Encoding: gzip
2023-08-15 14:38:38.483 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Accept-Encoding: deflate
2023-08-15 14:38:38.483 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Content-Encoding: gzip
2023-08-15 14:38:38.483 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Content-Encoding: deflate
2023-08-15 14:38:38.483 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Content-Length: 289891
2023-08-15 14:38:38.483 DEBUG 23664 --- [nio-8030-exec-1] com.morris.user.client.OrderClient       : [OrderClient#bigJson] Content-Type: application/json

注意:只有当Feign的Http组件不是okhttp3的时候,压缩才会生效,配置源码在FeignAcceptGzipEncodingAutoConfiguration

@Configuration(
    proxyBeanMethods = false
)
@EnableConfigurationProperties({FeignClientEncodingProperties.class})
@ConditionalOnClass({Feign.class})
@ConditionalOnBean({Client.class})
@ConditionalOnProperty(
    value = {"feign.compression.response.enabled"},
    matchIfMissing = false
)
@ConditionalOnMissingBean(
    type = {"okhttp3.OkHttpClient"}
)
@AutoConfigureAfter({FeignAutoConfiguration.class})
public class FeignAcceptGzipEncodingAutoConfiguration {
    public FeignAcceptGzipEncodingAutoConfiguration() {
    }

    @Bean
    public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
        return new FeignAcceptGzipEncodingInterceptor(properties);
    }
}

核心代码就是@ConditionalOnMissingBean(type=“okhttp3.OkHttpClient”),表示Spring BeanFactory中不包含指定的bean时条件匹配,也就是没有启用okhttp3时才会进行压缩配置。

编码器解码器配置

Feign中提供了自定义的编码解码器设置,同时也提供了多种编码器的实现,比如Gson、Jaxb、Jackson。我们可以用不同的编码解码器来处理数据的传输。如果你想传输XML格式的数据,可以自定义XML编码解码器来实现获取使用官方提供的Jaxb。

扩展点:Encoder & Decoder

public interface Encoder {
    void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
}
public interface Decoder {
    Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;
}

Java配置方式

配置编码解码器只需要在Feign的配置类中注册Decoder和Encoder这两个类即可:文章来源地址https://www.toymoban.com/news/detail-662864.html

@Bean
public Decoder decoder() {
    return new JacksonDecoder();
}
@Bean
public Encoder encoder() {
    return new JacksonEncoder();
}

yml配置方式

feign:
  client:
    config:
      order-service:  #对应微服务
        # 配置编解码器
        encoder: feign.jackson.JacksonEncoder
        decoder: feign.jackson.JacksonDecoder

到了这里,关于【openfeign】OpenFeign的扩展、日志、超时时间、拦截器、客户端组件、压缩的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloud GateWay网关通过全局拦截器GlobalFilter实现API日志

    产品经理突然找到我说,咱们这个产品貌似没有实现之前旧的系统平台操作日志了;希望我尽快实现这个需求,以应对一些检查;因为时间关系再加上人员问题,跟我原先规划得有些背道而驰 1.写一个AOP日志Starter,再需要的模块中引入,对应方法去标记注解,工程量比较大,

    2024年02月11日
    浏览(53)
  • Spring Boot入门(23):记录接口日志再也不难!用AOP和自定义注解给Spring Boot加上日志拦截器!

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(55)
  • springboot 日志记录接口的请求参数和响应结果的两种方式-拦截器和切面(具体代码)

    springboot 日志记录接口的请求参数和响应结果的两种方式-拦截器和切面(具体代码) 前言:在生产中如果出现问题,我们想要查看日志,某个时间段用户调用接口的请求参数和响应的返回结果,通过日志来推测下用户当时做了什么操作。日志记录接口的请求参数和响应结果有利

    2024年02月02日
    浏览(63)
  • 【常用的简单功能及算法】拦截器 加盐算法 深克隆 时间日期格式化 加盐算法 sql分页算法 验证码

    1.实现拦截器 Interceptor (以登录拦截器为例) 1.1 写一个登录拦截器普通类 实现HandlerInterceptor接口 重写preHandle方法 2.2 设置拦截规则 加@Configuration注解 实现WebMvcConfigurer接口 重写addInterceptors方法 2.深克隆方法 (spring提供的深克隆方法) 3.时间日期格式化  1. 全局日期格式化 这种

    2024年01月21日
    浏览(41)
  • SpringCloud OpenFeign 全功能配置详解(一文吃透OpenFeign)

    OpenFeign客户端是一个web声明式http远程调用工具,直接可以根据服务名称去注册中心拿到指定的服务IP集合,提供了接口和注解方式进行调用,内嵌集成了Ribbon本地负载均衡器。 1、底层都是内置了Ribbon,去调用注册中心的服务。 2、Feign是Netflix公司写的,是SpringCloud组件中的一

    2024年02月07日
    浏览(42)
  • 【OpenFeign】OpenFeign结合Hystrix和Sentinel实现熔断降级

    OpenFeign可以与Hystrix和Sentinel结合使用,实现降级和熔断。 使用OpenFeign需要引入OpenFeign的依赖: spring-cloud-starter-openfeign 引入的依赖如下: 默认已经自动引入了hystrix的依赖,不再需要单独再引入hystrix了。 降级方法的类需要实现FeignClient的接口,同时这个类需要注入到Spring容器

    2024年02月11日
    浏览(39)
  • SpringCloud入门(微服务调用 OpenFeign)——从RestTemplate到OpenFeign & OpenFeign的相关配置 & 源码的分析和请求流程拆解

    在之前的博客中,我们介绍了RestTemplate的使用,博客文章如下连接。但是在使用RestTemplate的时候,需要把生产者的路径拼出来,非常繁琐,另外参数的传递的也比较繁琐,解决方案就是使用openFeign。 SpringCloud入门(RestTemplate + Ribbon)——微服务调用的方式 RestTemplate的使用 使

    2024年04月11日
    浏览(37)
  • OpenFeign设置header

    设置Feign的Header信息(五种方式) 概述 在微服务间使用Feign进行远程调用时需要在 header 中添加信息,那么 springcloud open feign 如何设置 header 呢?有5种方式可以设置请求头信息: 在@RequestMapping注解里添加headers属性 在方法参数前面添加@RequestHeader注解 在方法或者类上添加@Headers的

    2024年02月08日
    浏览(28)
  • OpenFeign简介和使用详解

    1.1.OpenFeign是什么? Feign是一个声明式的Web服务客户端(Web服务客户端就是Http客户端),让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。 cloud官网介绍Feign:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/ OpenFeign源码:https://github.co

    2024年02月10日
    浏览(46)
  • SpringCloud OpenFeign

    Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单。 Feign是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。 OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@Reques

    2024年02月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包