Feign的覆写默认配置

A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the @FeignClient annotation. Spring Cloud creates a new ensemble as anApplicationContext on demand for each named client using FeignClientsConfiguration. This contains (amongst other things) an feign.Decoder, a feign.Encoder, and a feign.Contract.

上面是官网的API文档中的说明,如下是我的翻译:

Spring Cloud的Feign支持的一个中心概念是命名客户端。

每个feign client是整体的一部分,它们一起工作以按需联系远程服务器,并且该整体具有一个名称,开发人员可以使用@FeignClient将其命名。

Spring Cloud根据需要使用FeignClientsConfiguration为每个命名的客户端创建一个新的整体作为ApplicationContext。

这包含(其他)feign.Decoder,feign.Encoder和feign.Contract。

Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of theFeignClientsConfiguration) using @FeignClient. Example:

@FeignClient(name = “stores”, configuration = FooConfiguration.class)
public interface StoreClient {
//..
}

上面文档说,通过使用额外的配置@FeignClient注解,可以使Spring Cloud让你完全的控制feign客户端。

并且官网还给出了例子,那么我们也按照它提供的例子来在我们的工程师运用起来。

将接口类UserFeignClient进行修改,如下修改后的代码:

@FeignClient(name = "microservice-provider-user", configuration = FooConfiguration.class)
public interface UserFeignClient {
    /**
     * 注意:要使用Feign的注解
     * <p>
     * <code>@RequestLine("GET /repos/{owner}/{repo}/contributors")</code>
     * <br>
     * <code>List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);</code>
     * 
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/simple/{id}")
//  @RequestLine("GET /simple/{id}")
    public User findById(@PathVariable("id") Long id);
}

在配置FeignClient的configuration指定的值FooConfiguration,这个类是不存在的,这里我们需要新建,官网中也给我创建了这个类的代码,下面是我根据官网的代码和我实际需求修改后的:

@Configuration
public class FooConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}

完成之后,可以开始启动工程了,当我们在启动时,会报错,错误关键如下:

Caused by: java.lang.IllegalStateException: Method findById not annotated with HTTP method type (ex. GET, POST)

这里错误是说我们没有使用Http方法的注解导致的,但我们仔细检查下代码,我们使用的是@RequestMapping的注解方式,这里我也不知道怎么解释,可能是我没有深刻的理解吧,看了Feign 的GitHub的相关代码后,我发现了另一种注解方式:

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

好的,现在将@RequestMapping注解改成@RequestLine,以及参数也修改成@Param,修改后:

@FeignClient(name = "microservice-provider-user", configuration = FooConfiguration.class)
public interface UserFeignClient {
    /**
     * 注意:要使用Feign的注解
     * <p>
     * <code>@RequestLine("GET /repos/{owner}/{repo}/contributors")</code>
     * <br>
     * <code>List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);</code>
     * 
     * @param id
     * @return
     */
    @RequestLine("GET /simple/{id}")
    public User findById(@Param("id") Long id);
}

修改完成之后,再次重启服务,发现启动成功,而且可以访问接口了。

WARNING Previously, using the url attribute, did not require the name attribute. Using name is now required.

官网中有个这样的提醒:以前在使用URL属性时,不必要使用那么属性,但是在现在Feign中name属性就是必要的了。

它也给了例子,如下面代码:

@FeignClient(name = "${feign.name}", url = "${feign.url}")
public interface StoreClient {
    //..
}

现在我们也来在我们的工程中实际运用一下。

新建一个接口FeignClient2,代码如下:

@FeignClient(name = "xxx", url = "http://localhost:8761/", configuration = BeanConfiguration.class)
public interface FeignClient2 {
//  @RequestMapping(value = "/eureka/apps/{serviceName}")
    @RequestLine("GET /eureka/apps/{serviceName}")
    public String findServiceInfoEurekaByServieName(@Param("serviceName") String serviceName);
}

我们通过这个feign来获取eureka server下注册的实例信息,通过@FeignClient注解配置了name、url和configuration属性,这里那么我随便写的内容,因为这个仅仅表示这个feign的名称而已,url配置的是eureka server的地址,configuration我们这里配的一个需要新建的类BeanConfiguration。

大家肯定还有疑惑,这个BeanConfiguration类配置了是起什么作用的了?

好的,这里就为大家答疑解惑,首先贴出该类的代码:

@Configuration
public class BeanConfiguration {
    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("micheal", "123456");
    }
}

看到代码,也许大家可能就明白了,这个在请求时不需要输入用户名和密码就可以直接调用Eureka Server,因为Feign通过这个配置的configuration类为我们做了用户名和密码的权限认证了。

完成上面的内容了,接下来就是见证奇迹的时刻了。

启动服务,在Eureka Server中查看到注册成功了,我们就可以通过浏览器进行查看了。

Feign Logging 日志

A logger is created for each Feign client created. By default the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level.

application.yml
logging.level.project.user.UserClient: DEBUG

官网API说:为每个Feign 客户端创建日志,日志的默认名称为所创建的Feign客户端接口类的整个类名。Feign的日志仅仅只有在DEBUG级别时才会响应。

官网给我们提供了例子,按照官网提供的做法,现在来为我们对的工程配置Feign Logging。

以我们microservice-consumer-movie-feign-customizing工程为例,在配置文件application.yml进行Feign 日志配置,如下配置:

logging:
  level:
    com.spring.cloud.feign.UserFeignClient: DEBUG

com.spring.cloud.feign.UserFeignClient 是Feign Client接口类的完成类名。好了,完成了这个配置,是不是有点超激动想要一看是否真的能打印出日志了。

先不着急,我们接着查看官网API文档中的内容:

The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are:

• NONE, No logging (DEFAULT).

• BASIC, Log only the request method and URL and the response status code and execution time.

• HEADERS, Log the basic information along with request and response headers.

• FULL, Log the headers, body, and metadata for both requests and responses.

For example, the following would set the Logger.Level to FULL:

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

官网给我们提供了一些日志级别的等级,这里就不一一翻译了。我们的重点是在上面所给的例子,上面例子说为日志设置为FULL级别的日志。

好,开始我们的配置,找到我们所配Feign 日志的客户端接口类,我们发现我们配值得configuration的类时FooConfiguration类,好我们将官网中的feignLoggerLevel方法添加到我们的FooConfiguration类中。

完成之后,我们启动工程,并先将日志清掉,再重新请求接口,发现确实打印出日志来了。

这里还需要补充一下:在配置文件application.yml中配置了Feign客户端日志之后,如果不在configuration类中添加日志级别的话,是不会打印出日志的。因为在官网API中有提到“NONE, no loggin(DEFAULT)”,就是说默认日志级别时NONE的。

Feign进行日志配置

在微服务项目中项目启动遇到 bug 时,很多方面的错误都有可能出现,比如参数错误,接口调用错误等,或者是想了解服务接口的使用量和性能。

首先 Feign 支持自定义日志的配置,配置 Feign 的日志信息是针对以上情况效率很高的一种解决方案。

Feign有四种类型的日志

  • NONE:不记录任何日志信息,默认是 NONE 配置。
  • BASIC:只记录发起请求的方法,请求的 URL 地址,请求状态码和请求的响应时间。
  • HEADERS:在 BASIC 级别的基础上,还多记录了请求头和响应头的信息。
  • FULL:记录所有的日志信息,包括请求和响应的所有具体信息。

列出两种在项目中配置Feign日志的方法

一:在配置文件中配置 Feign 的日志

feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别

其中 default 表示全局配置日志,将 default 改为具体的服务名称,表示在调用这个服务的时候才会记录日志。

loggerLevel 表示日志的水平,包含 NONE、BASIC、HEADERS、FULL 四种级别的日志。

二:通过配置类的方式

声明一个类,取名为 FeignLoggerConfiguration。在类中声明一个 Logger.Level 对象并返回日志级别,这里设置级别为 BASIC ,通过 @Bean 注解将该方法设置为 IOC 容器的组件。

public class FeignLevelConfiguration {
    @Bean
    public Logger.Level logLevel(){
        return Logger.Level.BASIC;
    }
}

同样的可以设置全局配置和局部给某个服务配置。

全局配置:

在启动类的 @EnableFeignClients 注解中加上参数

defaultConfiguration = FeignLoggerConfiguration .class

这里的 FeignLoggerConfiguration.class要和配置的日志类一致。

局部配置:

在配置了 Feign 的服务接口上的注解 @FeignClient("要调用的服务名称") 加上参数

configuration = FeignLoggerConfiguration .class

这里设置调用的服务名称为 testservice ,则注解改为

@FeignClient(value = "testservice", configuration = FeignLoggerConfiguration .class) 

这里的 FeignLoggerConfiguration.class 就是上面的日志配置类。

同时,在优化 Feign 时可以从日志的级别入手,日志尽量使用 Basic 级别,因为打印日志太多会消耗 Feign 的性能。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持Devmax。

关于Feign的覆写默认配置和Feign的日志的更多相关文章

  1. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  2. 使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. Yii2语言国际化自动配置详解

    这篇文章主要介绍了Yii2语言国际化自动配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. SpringMVC静态资源配置过程详解

    在javaweb项目中配置了DispatcherServlet的情况下,如果不进行额外配置的话,几乎所有的请求都会走这个servlet来处理,默认静态资源按路径是访问不到的会报404错误,下面就来讲一讲如何配置才能访问到静态资源吧

  5. Laravel 重写日志,让日志更优雅

    这篇文章主要介绍了Laravel 重写日志,让日志更优雅,laravel框架俗称优雅的框架,所以有想对laravel中的日志重写使其更加方便的记录信息获取信息的同学可以参考下

  6. 关于@RequestLine的使用及配置

    这篇文章主要介绍了关于@RequestLine的使用及配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Spring Cloud超详细i讲解Feign自定义配置与使用

    这篇文章主要介绍了SpringCloud Feign自定义配置与使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. SpringBoot配置拦截器实现过程详解

    在系统中经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中,即平时所说的"权限检测"及"日志记录",下面这篇文章主要给大家介绍了关于在SpringBoot项目中整合拦截器的相关资料,需要的朋友可以参考下

  9. Spring Boot日志的打印与持久化详细解析

    Spring Boot默认使用SLF4J+Logback 记录日志,并提供了默认配置,即使我们不进行任何额外配,也可以使用SLF4J+Logback进行日志输出

  10. SpringBoot浅析安全管理之Spring Security配置

    安全管理是软件系统必不可少的的功能。根据经典的“墨菲定律”——凡是可能,总会发生。如果系统存在安全隐患,最终必然会出现问题,这篇文章主要介绍了SpringBoot安全管理Spring Security基本配置

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部