Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送

一 基本使用

1 在消费者中引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2 增加启动注解

在消费者启动类上添加 @EnableFeignClients 注解,提供者可不添加

3 编写 Feign 接口

@FeignClient("userservice") //服务名称
public interface UserClient {

     @GetMapping("/hello/feignTest/{id}") //地址必须与服务中的地址一致
     String feignTest(@PathVariable("id") String id);
}

//提供者中代码

@RestController
@RequestMapping("/hello")
public class Hello {

    @GetMapping("/hello")
    private String hello() {
        return "userHello";
    }

    @GetMapping("feignTest/{id}")
    private String feignTest(@PathVariable("id") String id){
        return "feignTest, ID:"+id;
    }
}

4 注入调用

//消费者中注入调用

@RestController
@RequestMapping("/hello")
public class Hello {

    @Autowired
    private UserClient userClient;

    @GetMapping("/hello")
    private String hello() {
        return "orderHello";
    }

    @GetMapping("/feign/{id}")
    private String feign(@PathVariable("id")String id ){
        return userClient.feignTest(id);
    }

}

二 自定义配置

Feign可以支持很多的自定义配置,如下表所示:

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

一般只会修改日志的配置

feign日志级别:

  • none(默认) 无日志
  • basic 记录请求发送、结束时间、耗时等基本信息
  • headers basic的信息+请求头、响应头信息
  • full headers+请求体、响应体

自定义的方式分为代码和配置文件(都是在消费者模块中添加)

配置文件方式:

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

代码方式:

public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志级别为BASIC
    }
}

针对单个服务则在单个服务的 @FeignClient 中添加 configuration = xxx.class

@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)

针对所有服务则在启动类 @EnableFeignClients 中添加 defaultConfiguration = xxx.class

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)

三Feign使用优化

1 优化日志级别

优化日志级别为 none 或 basic

2 http客户端优化

feign本身只是远程调用的申明,底层还是需要http客户端进行远程调用

feign的客户端有:

  • URLConnection:默认实现,不支持连接池
  • Apache HttpClient :支持连接池
  • OKHttp:支持连接池

只需要替换成带连接池的 HttpClient 或 OKHttp 则可以提升性能

以 HttpClient 为例

1 在消费者中引入依赖

<!--httpClient的依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

2 修改配置文件中feign相关的配置

feign:
  client:
    config:
      default: # default全局的配置
        loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    time-to-live: 900 # 连接最大闲置时间,单位为秒,缺省值是 900秒(15分钟)
    max-connections-per-route: 50 # 每个路径的最大连接数

四 Feign项目中的使用

项目中使用方法一般分为 继承 或者 单独抽离成一个模块

1 继承

2.png

让Feign接口和服务提供者继承或实现同一个接口,达到两边的统一性(紧耦合,耦合度高)

2 单独抽离成一个模块

把feign相关的代码(feign接口、配置文件、依赖、相关实体类 )抽离成一个单独的模块,要使用其中的feign接口直接引入该模块
3.png

引入feign模块的方式可能会导致消费者无法注入对应的 feign 接口类
解决方法:

  • 指定要加载的Feign接口类:在启动类的@EnableFeignClients中添加 clients = {xxxx.class,xxx.class}
  • 指定Feign应该扫描的包:在启动类的 @EnableFeignClients 中添加 basePackages = "xxx.xxx.xxx.xxx"

//样例
指定需要加载的Client接口:

@EnableFeignClients(clients = {UserClient.class})

指定Feign应该扫描的包:

@EnableFeignClients(basePackages = "com.ray.feignapi.clients")

不语
4 声望1 粉丝