简介

Feign是Netflix开源的声明式HTTP客户端

GitHub

引入依赖

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

在Springboot的启动类上加上注解 @EnableFeignClients

修改之前的代码

@FeignClient(name = "user-center")
public interface UserCenterFeignClient {

    @GetMapping("/users/{id}")
    UserDTO findById(@PathVariable Integer id);
}
private final UserCenterFeignClient userCenterFeignClient;

public ShareDTO findById(Integer id) {
		// 更改之后的调用HTTP
        UserDTO userDTO = this.userCenterFeignClient.findById(userId);
        return null;
    }

Feign的组成

Feign的组成

Feign配置

Feign的日志级别

日志级别

Java代码细粒度配置
/**
 * 如果加了configuration注解,就把代码放到启动类之外的包
 * 是由于 父子上下文,重复扫描的问题
 */
public class UserCenterFeignConfiguration {
    @Bean
    public Logger.Level level() {
    	// 让feign打印所有的细节
        return Logger.Level.FULL;
    }
}
@FeignClient(name = "user-center",configuration = UserCenterFeignConfiguration.class)
public interface UserCenterFeignClient {

    @GetMapping("/users/{id}")
    UserDTO findById(@PathVariable Integer id);
}
logging:
  level:
    #把要打印日志的包全路径copy过来选择日志级别
    com.itmuch.contentcenter.feignclient.UserCenterFeignClient: debug
属性细粒度配置
// 去掉刚才的configuration 
@FeignClient(name = "user-center")
public interface UserCenterFeignClient {

    @GetMapping("/users/{id}")
    UserDTO findById(@PathVariable Integer id);
}
feign:
  client:
    config:
      # 想要调用的微服务名称
      user-center:
        loggerLevel: full
Java全局配置自定义

在启动类上的注解@EnableFeignClients进行配置

@EnableFeignClients(defaultConfiguration = UserCenterFeignConfiguration.class)
public class UserCenterFeignConfiguration {
    @Bean
    public Logger.Level level() {
        return Logger.Level.FULL;
    }
}
属性全局配置自定义
feign:
  client:
    config:
      # 全局配置
      default: 
        loggerLevel: full
代码方式支持的配置项

代码方式支持的配置项

属性方式支持的配置项

属性方式支持的配置项

Ribbon配置和Feign配置对比

Ribbon配置和Feign配置对比

Feign代码方式配置对比属性方式

代码方式配置对比属性方式
优先级:
全局代码配置<全局属性<细粒度代码配置<细粒度属性配置

Feign的继承特性

Feign的继承是将一些通用代码抽离出来成为一个单独的maven,然后可以在各微服务直接调用,比如在微服务A调用微服务B的时候有通用的调用的时候就可以抽离出来,比如返回一个User对象,这个对象理由有一个属性,如果采用了继承特性,那么在编写的时候一般就不会出现什么问题;如果没有采用继承特性,比如在微服务A中的User对象增加了一些属性,而在微服务B调用A的这个接口获取User对象的时候,B并没有增加那些属性,这就会导致JSON报错,因为跟结果对不上。
官方的建议是不采用这个特性,因为这会导致微服务的紧耦合,这就背离了微服务的初衷。
所以还是需要权衡利弊来使用这个继承特性。

构造多参数请求

user-center

	@GetMapping("/q")
    public User query(User user) {
        return user;
    }

content-center

@FeignClient(name = "user-center")
public interface TestUserCenterFeignClient {
    @GetMapping("/q")
    public UserDTO query(@SpringQueryMap UserDTO userDTO);
}
	@Autowired
    private TestUserCenterFeignClient testUserCenterFeignClient;

    @GetMapping("test-get")
    public UserDTO query(UserDTO userDTO) {
        return testUserCenterFeignClient.query(userDTO);
    }

测试结果

Feign脱离Ribbon使用

// 名字可以随便取,但是一定要有
@FeignClient(name = "baidu", url = "http://www.baidu.com")
public interface TestBaiduFeignClient {

    @GetMapping
    String index();
}
 @Autowired
    private TestBaiduFeignClient testBaiduFeignClient;

    @GetMapping("baidu")
    public String baiduIndex() {
        return this.testBaiduFeignClient.index();
    }

访问结果

RestTemplate vs Feign

RestTemplate vs Feign
个人看法:尽量使用Feign,杜绝使用RestTemplate;具体视情况合理使用。

Fegin的性能优化

连接池(提升15%左右)

使用apache的Httpclient
引入依赖

<dependency>
	<groupId>io.github.openfeign</groupId>
	<artifactId>feign-httpclient</artifactId>
</dependency>
feign:
  httpclient:
    #让feign使用apache httpclient做请求,而不是默认的urlconnection
    enabled: true
    # feign最大连接数
    max-connections: 200
    # fegin 单个路径的最大连接数
    max-connections-per-route: 50

使用Okhttp
引入依赖

<dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
            <version>10.2.0</version>
        </dependency>
feign:
  okhttp:
    enabled: true
日志级别(生产环境建议BASIC)
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐