欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Cloud 七:Feign介绍与使用

程序员文章站 2022-03-21 07:52:30
一,理解Feign1,什么是FeignNetflix FeignFeign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。Feign实际上是对普通HTTP客户端的一层封装,其目的是降低集成成本、提升可靠性。Feign支持三种HTTP客户端,包括JDK自带的HttpURLConnection、Apache HttpClient和Square OkHttp,默认使用Apache HttpClient。Spring Cloud Feign...

一,理解Feign

1,什么是Feign

Netflix Feign

Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。

Feign实际上是对普通HTTP客户端的一层封装,其目的是降低集成成本、提升可靠性。Feign支持三种HTTP客户端,包括JDK自带的HttpURLConnection、Apache HttpClient和Square OkHttp,默认使用Apache HttpClient。

Spring Cloud Feign

Spring Cloud Feign是基于Netflix Feign实现,对Netflix Feign进行了增强,使Feign支持了Spring MVC注解,整合了Spring Cloud Ribbon和Spring Cloud Hystrix 提供负载均衡和断路器。

2,Feign和Open Feign

其实Feign和Open Feign他俩是属于同一个东西,Feign仅仅只是改名成为了Open Feign而已,然后Open Feign项目在其基础上继续发展至今。

spring-cloud-starter-feign 1.2.0.RELEASE开始 已放弃Netflix Feign而全面使用更新的Open Feign版本,

spring-cloud-starter-openfeign更是和Netflix Feign已经没有关系了。

二,Feign的使用

1,服务消费方使用

1.1,起一个eureka服务:

Spring Cloud 七:Feign介绍与使用

1.2,向eureka-server中注册一个服务提供者eureka-provider

application.yaml

spring:
  application:
    name: eureka-provider
eureka:
  client:
    service-url:
      defaultZone: http://euk-server1:7001/eureka/
  instance:
    hostname: euk-client1

HelloController.java

@RestController
public class HelloController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/testFeign")
    public String testFeign() {
        System.out.println("port:" + port);
        return "服务提供者,端口为:" + port;
    }
}

Spring Cloud 七:Feign介绍与使用

1.3,使用Feign向eureka-server注册服务消费者

导入Open Feign

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

配置appliation.yml 注册到Eureka Server。

eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      defaultZone: http://euk-server1:7001/eureka/
spring:
  application:
    name: eureka-consumer
server:
  port: 7008

使用@FeignClient为本应用声明一个简单的能调用的客户端,value是需要调用的服务名。

@FeignClient(value = "eureka-provider")
public interface FeignInterface {
    @RequestMapping("/testFeign")
    public String testFeign();
}

接收外部请求,通过Feign远程调用服务

@RestController
public class FeignController {
    @Autowired
    private FeignInterface feignInterface;

    @RequestMapping("/testFeign")
    public String testFeign() {
        return feignInterface.testFeign();
    }
}

在启动类上添加 @EnableFeignClients 启用 Feign

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaConsumer1Application {

    public static void main(String[] args) {
        SpringApplication.run(EurekaConsumer1Application.class, args);
    }
}

启动eureka-consumer然后访问http://localhost:7008/testFeign 返回结果:

Spring Cloud 七:Feign介绍与使用

2,Fegin的继承特性使用

Spring Cloud Feign提供了继承特性,所谓的继承特性就是将一些公共操作提取到一个父接口中,从而继承父接口中的操作,减少代码的重复开发,节约开发成本。

  1. 编写通用服务接口A,接口方法上写@RequestMapping(),此接口用于 feign。
  2. 服务提供者 实现上面接口A。
  3. 服务消费者的feign client接口 继承A。

优点:

可以将接口的定义从 Controller 中剥离,同时配合 Maven 私有仓库就可以轻易地实现接口定义的共享,不用再复制粘贴接口进行绑定,而是实现在构建期的接口绑定,从而有效减少服务客户端的绑定配置。

缺点:

由于接口在构建期间就建立起了依赖,那么接口变动就会对项目构建造成影响,可能服务提供方修改了一个接口定义,那么会直接导致客户端工程的构建失败。

2.1:首先我们新建一个通用model,eureka-feign-api

由于我们要用到spring mvc,所以pom.xml中要依赖spring web模块

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

创建通用接口HelloInterface.java,用于eureka-provider实现,eureka-consumer继承:

@RequestMapping("/feign")
@RestController
public interface HelloInterface {
    @GetMapping("/hello")
    String hello();
}

2.2:eureka-provider依赖eureka-feign-api并实现其通用接口HelloInterface

eureka-provider的pom添加依赖eureka-feign-api

<dependency>
     <groupId>com.bobo</groupId>
     <artifactId>eureka-feign-api</artifactId>
     <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

eureka-provider的controller实现通用接口HelloInterface

@RestController
public class FeignCommonProviderController implements HelloInterface {

    @Value("${server.port}")
    private int port;

    @Override
    public String hello() {
        return "服务提供者,我的端口为:" + port;
    }
}

eureka-provider启动类

@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class, args);
    }

}

3.3:eureka-consumer依赖eureka-feign-api并继承其通用接口HelloInterface

eureka-consumer的pom依赖添加eureka-feign-api

<dependency>
     <groupId>com.bobo</groupId>
     <artifactId>eureka-feign-api</artifactId>
     <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

eureka-consumer继承通用接口HelloInterface

@FeignClient("eureka-provider")
public interface FeignCommonInterface extends HelloInterface {
}

eureka-consumer通过FeignCommonInterface来实现Feign的调用

@RestController
public class FeignCommonController {
    @Autowired
    private FeignCommonInterface commonInterface;

    @GetMapping("/hello")
    public String hello(){
        return commonInterface.hello();
    }
}

eureka-consumer启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class EurekaConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaConsumerApplication.class, args);
    }

}

然后启动eureka-server,eureka-provider,eureka-consumer,通过服务调用eureka-consumer

http://euk-client2:7008/hello 输出:

Spring Cloud 七:Feign介绍与使用

三,Feign配置

feign的默认配置类是:org.springframework.cloud.openfeign.FeignClientsConfiguration。默认定义了feign使用的编码器,解码器等。

Feign允许自定义配置,自定义配置有如下两种方式:

  1. 一种是Java 代码配置,需要在@FeignClient(name = “eureka-consumer”,configuration = FeignAuthConfiguration.class)来引用配置。
  2. 第二种是直接配置文件配置,在application.yml或者application.properties中配置。

1,Java代码配置

public class FeignAutoConfiguration {
    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("root", "root");
    }
}
@FeignClient(value = "eureka-provider",configuration = FeignAutoConfiguration.class)
public interface FeignCommonInterface extends HelloInterface {
}

如果在配置类上添加了@Configuration注解,并且该类在@ComponentScan所扫描的包中,那么该类中的配置信息就会被所有的@FeignClient共享。

最佳实践是:不指定@Configuration注解,而是手动:@FeignClient(name = “eureka-provider”,configuration = FeignAuthConfiguration.class)

2,配置文件配置

自定义拦截器:

/**
 * @author bobo
 * @date 2020-12-08
 * 自定义拦截器
 */

public class MyBasicAuthRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("Authorization", "Basic cm9vdDpyb290");
    }
}

application.yaml

spring:
  application:
    name: eureka-consumer
eureka:
  client:
    service-url:
      defaultZone: http://euk-server1:7001/eureka/
  instance:
    hostname: euk-client2
server:
  port: 7008

feign:
  client:
    config:
      eureka-peovider:
        request-interceptors:
           com.bobo.eurekaconsumer.MyBasicAuthRequestInterceptor

3,扩展

自定服务名称配置:

  feign:
     client: 
       config:  
         service-valuation: 
           connect-timeout: 5000
           read-timeout: 5000
           logger-level: full

通用配置:

  feign:
     client: 
       config:  
         default: 
           connect-timeout: 5000
           read-timeout: 5000
           logger-level: full

4,Feign压缩

Spring Cloud Feign 支持请求和响应进行GZIP压缩来提高通信效率,但是会增加CPU压力,建议把最小压缩的文档大小适度调大一点,进行gzip压缩。

 	 # 开启GZIP压缩配置:
      
      #请求GZIP压缩
      feign.compression.request.enable=true                 
      #响应GIZP压缩
      feign.compression.response.enable=true              
      #压缩支持的mime type
      feign.compression.request.mime-types=text/xml,application/xml.application/json                  
      feign.compression.request.min-request-size=1024         
      #压缩数据大小的最小值

5,Feign日志

Feign 为每一个FeignClient都提供了feign.logger实例,可在配置中或者java代码中开启日志。

feign:
  client: 
    config:  
	  # 服务名称
      eureka-provider:  
        logger-level: basic

上面logger-level有4种日志类型:

  1. none:不记录任何日志,默认值。
  2. basic:仅记录请求方法,url,响应状态码,执行时间。
  3. headers:在basic基础上,记录header信息。
  4. full:记录请求和响应的header,body,元数据。

上面的logger-level只对下面的 debug级别日志做出响应:

logging:
  level:
    com.bobo.eureka-consumer.ServiceForecast: debug

四,写在最后

上述例子代码已上传码云:https://gitee.com/songbozhao/spring-cloud-feign-test

本文地址:https://blog.csdn.net/u013277209/article/details/110881354