关于Feign的覆写默认配置和Feign的日志

目录
  • Feign的覆写默认配置
  • Feign Logging 日志
  • Feign进行日志配置
    • Feign有四种类型的日志
    • 列出两种在项目中配置Feign日志的方法

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 的性能。

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

(0)

相关推荐

  • feign 打印日志不显示的问题及解决

    目录 feign打印日志不显示 feign基本使用 Feign 概述 Feign 入门案例 Feign 工作原理 feign打印日志不显示 1.是否有设置 feign 的 Logger.Level @Configuration public class FeignClientConfig {     @Bean     Logger.Level feignLogLevel() {         return Logger.Level.FULL;     } } 2.查看是否有在 yml 或者

  • 如何使用Spring Cloud Feign日志查看请求响应

    这篇文章主要介绍了如何使用Spring Cloud Feign日志查看请求响应,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在使用微服务时,常常会用feign做客户端去调用别的微服务,但是在日志中很难查看到具体的请求和响应.因此,需要把feign默认的日志打开. 日志设置创建feign配置类 @Configuration public class FeignLogConfiguration { @Bean Logger.Level feign

  • 如何解决springcloud feign 首次调用100%失败的问题

    叙述 在高并发情况下发布应用时,经常会发现监控中有很多超时报错或者断路器打开,下图中可以看到监控情况,测试时也会偶现第一次feign调用出错,第二次就会恢复正常. 分析 大家都知道,这里feign底层是集成的ribbon,这里ribbon也会有http连接池,这里的连接池是长连接,定时初始化一批并销毁旧连接,这里还包括一些上下文需要初始化,但是在容器初始化好时,ribbon底层的client是未初始化的,当第一次调用时,有一个初始化过程会导致超时,一般情况下会说需要调整超时时间,但是在电商高并发

  • SpringCloud学习笔记之OpenFeign进行服务调用

    目录 前言 1.OpenFeign 1.1.OpenFeign概述 1.2.OpenFeign的使用步骤 1.3.超时控制 1.3.1.是什么? 1.3.2.修改代码设置超时错误 1.3.3.进行超时配置 1.4.日志打印 1.4.1.是什么? 1.4.2.日志级别 1.4.3.如何开启日志打印 总结 前言 Feign是一个声明式的Web服务客户端,是面向接口编程的.也就是说使用Feign,只需要创建一个接口并使用注解方式配置它,就可以完成对微服务提供方的接口绑定. 在使用RestTemplat

  • 关于Feign的覆写默认配置和Feign的日志

    目录 Feign的覆写默认配置 Feign Logging 日志 Feign进行日志配置 Feign有四种类型的日志 列出两种在项目中配置Feign日志的方法 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 c

  • Spring Cloud 覆写远端的配置属性实例详解

    应用的配置源通常都是远端的Config Server服务器,默认情况下,本地的配置优先级低于远端配置仓库.如果想实现本地应用的系统变量和config文件覆盖远端仓库中的属性值,可以通过如下设置: spring: cloud: config: allowOverride: true overrideNone: true overrideSystemProperties: false overrideNone:当allowOverride为true时,overrideNone设置为true,外部的配

  • 提升PHP安全:8个必须修改的PHP默认配置

    很明显,PHP+Mysql+Apache是很流行的web技术,这个组合功能强大,可扩展性强,还是免费的.然而,PHP的默认设置对已经上线的网站不是那么适合.下面通过修改默认的配置文件加强PHP的安全策略! 0x01:禁用远程url文件处理功能 像fopen的文件处理函数,接受文件的rul参数(例如:fopen('http://www.yoursite.com','r')).),这个功能可以很轻松的访问远程资源,然而,这是一个很重要的安全威胁,禁用这个功能来限制file function是个不错的

  • linux烧写、配置、搭建Edison环境

    小编发现很多朋友在linux上烧写.配置.搭建Edison环境的时候出现过很多问题,基本上很多人使用setup tool for ubuntu,小编在此先提醒各位,千万别用! 首先我们先来看下Edison入门环境配置相关的内容 文档说明:本文的阅读对象适合刚入手Edison并且在linux系统下操作的开发人员,所有操作均在linux系统下完成,主要内容包括Edison板级基本配置,Arduino IDE和Eclipse IDE开发环境的配置,固件的更新,本机编译和交叉编译的实现等,通过对这些基本

  • 利用Node.js如何实现文件循环覆写

    前言 这次编写Node.js项目的时候用到了日志模块,其中碰到了一个小问题. 这是一个定时执行可配置自动化任务的项目,所以输出信息会不断增加,也就意味着日志文件会随时间不断增大.如果对日志文件大小不加以控制,那么服务器的磁盘迟早会被撑满.所以限制文件大小是有必要的. 最理想的控制方式就是当文件大小超过限制时,清除最先记录的数据.类似一个FIFO的队列. # 删除前面的数据 - 1 xxx ...... 100 abc # 文件末尾追加数据 + 101 xxxx log4js的file rolli

  • 解决Kotlin 类在实现多个接口,覆写多个接口中相同方法冲突的问题

    一.首先来看一个例子 package net.println.kotlin.chapter4 /** * @author:wangdong * @description:类实现接口的冲突问题 */ interface B{ fun x(): Int = 1 } interface C{ fun x(): Int = 0 } /**一个类实现了两个接口,两个接口中的方法相同,这个类在覆写的时候就会出现冲突*/ class D: B,C{ //当下面两个方法同时存在的时候,就会报方法相同的冲突 ov

  • 详解java重载与覆写的区别

    很多同学对于overload和override傻傻分不清楚,建议不要死记硬背概念性的知识,要理解着去记忆. 先给出我的定义: 首先我们来讲讲:重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载Overloading是一个类中多态性的一种表现. (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义.调用方法时通过传递给它们的不同参数个数和参数类型来决定

  • Android开发中Launcher3常见默认配置修改方法总结

    本文实例讲述了Android开发中Launcher3常见默认配置修改方法.分享给大家供大家参考,具体如下: Launcher概述 Launcher是开机完成后第一个启动的应用,用来展示应用列表和快捷方式.小部件等.Launcher作为第一个(开机后第一个启动的应用)展示给用户的应用程序,其设计的好坏影响到用户的体验,甚至影响用户购机的判断.所以很多品牌厂商都会不遗余力的对Launcher进行深度定制,如小米的MIUI.华为的EMUI等.Android默认的Launcher没有过多的定制,更加简洁

  • 修改Nodejs内置的npm默认配置路径方法

    Nodejs 内置的npm默认会把模块安装在c盘的用户AppData目录下(吐槽一下:不明白为啥现在的软件都喜欢把资源装在这里) C盘这么小,肯定是不行的,下面一步步修改到D盘 1.打开cmd命令行,查看当前配置 输入 npm config ls 先看一下当前npm的配置环境,由于我已经修改过,所以可以看到修改后的路径 2.修改路径 这里需要修改两个路径,module路径和cache路径 module对应prefix cache对应cache 首先在别的盘新建两个目录 D:\nodejs\nod

  • Java的覆写操作实例分析

    本文实例讲述了Java的覆写操作.分享给大家供大家参考,具体如下: 一 属性覆写 1 点睛 所谓属性覆写,指的是子类定义和父类定义之中名称相同的属性. 2 代码 class Book { String info = "Hello World." ; // 如果加上private,1处的代码就会编译不过 } class ComputerBook extends Book { int info = 100 ; // 属性名称相同 public void print() { System.o

随机推荐