Netflix之Feign

发布时间 2023-10-07 12:51:59作者: -Lucas

一、什么是Feign

Feign是Netflix开发的一套声明式、模板话的http请求客户端,更便捷优雅的迪用API。
会根据带有注解的函数信息构建网络请求模板,在请求发送之前,将函数的参数值设置到请求模板中。
是一个http请求的轻量级框架,封装了http调用流程,面向接口编程,可以以接口注解的方式调用http请求,而不用向java中封装请求报文的方式直接调用,通过处理注解,将请求模板化,当实际调用的时候传入参数,根据参数再应用到请求上,进而转化成真正的请求。
可以集成ribbon和hystrix,提供负载均衡和断路器机制。

二、Feign和OpenFeign的关系

Feign有一套自己独立的主角,不支持SpringMVC的注解。所以有了OpenFeign,它是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。
OpenFeign的@FeignClient注解可以解析@RequestMapping注解下的一些接口,并通过动态代理的方式产生实现类,实现类中负载均衡调用其他服务。

三、配置使用

1、依赖

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

2、当前服务需要连接Eureka服务器
3、启动类添加@EnableFeignClients注解
4、Feign默认所有带参数的请求都是Post,想要使用指定的提交方式需引入依赖

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

四、配置权限

1、feign的默认配置类是:org.springframework.cloud.openfeign.FeignClientsConfiguration。默认定义了feign使用的编码器,解码器等。
允许使用@FeignClient的configuration的属性自定义Feign配置。自定义的配置优先级高于上面的FeignClientsConfiguration。

开放权限:
<!-- 安全认证 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 关闭csrf
		http.csrf().disable();
		// 表示所有的访问都必须认证,认证处理后才可以正常进行
		http.httpBasic().and().authorizeRequests().anyRequest().fullyAuthenticated();
		// 所有的rest服务一定要设置为无状态,以提升操作效率和性能
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
	}
}
		
spring: 
  security: 
    user: 
      name: root
      password: root
  

2、自定义配置配

配置类:
public class FeignAuthConfiguration {
	
	@Bean
	public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
		return new BasicAuthRequestInterceptor("root", "root");
	}
}

在feign上加配置
@FeignClient(name = "service-auth",configuration = FeignAuthConfiguration.class)
//如果在配置类上添加了@Configuration注解,并且该类在@ComponentScan所扫描的包中,那么该类中的配置信息就会被所有的@FeignClient共享。最佳实践是:不指定@Configuration注解(或者指定configuration,用注解忽略),而是手动:
//@FeignClient(name = "service-auth",configuration = FeignAuthConfiguration.class)

3、拦截器

import feign.RequestInterceptor;
import feign.RequestTemplate;

public class MyBasicAuthRequestInterceptor implements RequestInterceptor {
	@Override
	public void apply(RequestTemplate template) {
		// TODO Auto-generated method stub
		template.header("Authorization", "Basic cm9vdDpyb290");
	}
}

feign:
  client: 
    config:  
      service-auth: 
        request-interceptors:
        - com.xinay.feign.interceptor.MyBasicAuthRequestInterceptor
# 对指定服务进行配置
feign:
 client: 
   config:  
     service-auth: 
       connect-timeout: 5000
       read-timeout: 5000
       logger-level: full
# 通用配置
feign:
 client: 
   config:  
     default: 
       connect-timeout: 5000
       read-timeout: 5000
       logger-level: full
# 属性配置默认比java代码配置优先级高  可以通过此项配置调整
feign:
  client: 
	default-to-properties: false

五、原理

1、主程序入口添加@EnableFeignClients注解开启对Feign Client扫描加载处理。
2、当程序启动时,会进行包扫描,扫描所有添加@FeignClient注解的类,将这些信息注入Spring IOC容器中,当定义的Feign接口中的方法被调用时,通过JDK代理为每一个方法生成具体的RequestTemplate对象,这个对象封装了http请求需要的全部信息,如请求参数名、请求方法等信息都在这个过程中确定。
3、然后由RequestTemplate生成Request,然后把这个Request交给Client(JDK原生的URLConnection/Apache的HttpClient/Okhttp)处理,最后Client被封装到LoadBalanceClient类,结合ribbon负载均衡发起服务之前的调用。

六、压缩

#服务端开启压缩
server.compression.enabled=true

#调用方配置
#配置请求GZIP压缩
feign.compression.request.enabled=true
#配置响应GZIP压缩
feign.compression.response.enabled=true
#单位是B
feign.compression.request.min-request-size=100