1 初识Feign

1.1 Feign是什么?

Feign是声明式的Web服务客户端。它使编写Web服务客户端更加容易。要使用Feign,请创建一个接口并添加注解。它支持可插拔的注解,包括Feign注解和JAX-RS(Java API for RESTful Web Services)注解。

Feign还支持可插拔的编码器和解码器。 Spring Cloud添加了对Spring MVC注解的支持,并支持使用Spring Web中默认使用的相同的HttpMessageConverters。 Spring Cloud集成了Eureka和Spring Cloud LoadBalancer,以在使用Feign时提供负载均衡的http客户端。

分布式系统实现远程调用的方式很多。按照协议划分,有 RPC,Webservice,http。不同协议下也有不同的框架实现,比如 dubbo 就是 RPC 框架,而本教程所讲解的 Feign 便可理解为一种 http 协议的框架实现,用于分布式服务之间通过 Http 进行远程调用。

1.2 项目中如何引用Feign?

在项目的 pom.xml 文件中使用

  • group为org.springframework.cloud
  • artifact id为spring-cloud-starter-openfeign

的起步依赖即可。

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

spring boot 应用的启动类

@SpringBootApplication
@EnableFeignClients
public class Application {

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

}

StoreClient.java

@FeignClient("stores")
public interface StoreClient {
    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    List<Store> getStores();

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);
}

1.3 代码解释

@FeignClient注解中,String值(上面的“stores”)是一个任意的客户端名称,用于创建负载均衡器的客户端。也可以使用url属性(绝对值或仅是主机名)指定URL。应用程序上下文中的Bean名称是接口的全限定名称。如果想要指定别名,那么还可以指定@FeignClient注解的qualifier属性值哦。

上面的负载均衡器客户端将要发现“stores”服务的物理地址。
如果你的应用程序是Eureka客户端,则它将在Eureka服务的注册表中解析该服务。如果你不想使用Eureka,则可以使用SimpleDiscoveryClient在外部配置中简单地配置服务器列表。

openFeign

SpringCloud微服务实战(5)-Feign应用通信_微服务

2 SpringCloud中服务间两种restful调用方式
  • RestTemplate
  • Feign

RestTemplate的三种使用方式

SpringCloud微服务实战(5)-Feign应用通信_微服务_02
SpringCloud微服务实战(5)-Feign应用通信_微服务_03

3 负载均衡器:Ribbion
  • RestTemplate
  • Feign
  • Zuul
  • ServerList
  • IRule
  • ServerListFilter
4 追踪源码自定义负载均衡策略

SpringCloud微服务实战(5)-Feign应用通信_微服务_04
SpringCloud微服务实战(5)-Feign应用通信_微服务_05
SpringCloud微服务实战(5)-Feign应用通信_微服务_06
SpringCloud微服务实战(5)-Feign应用通信_微服务_07
SpringCloud微服务实战(5)-Feign应用通信_微服务_08
SpringCloud微服务实战(5)-Feign应用通信_微服务_09
SpringCloud微服务实战(5)-Feign应用通信_微服务_10
SpringCloud微服务实战(5)-Feign应用通信_微服务_11
SpringCloud微服务实战(5)-Feign应用通信_微服务_12
SpringCloud微服务实战(5)-Feign应用通信_微服务_13
SpringCloud微服务实战(5)-Feign应用通信_微服务_14

启动两个 Product 服务
SpringCloud微服务实战(5)-Feign应用通信_微服务_15
SpringCloud微服务实战(5)-Feign应用通信_微服务_16
再 debug 启动 Order 服务
SpringCloud微服务实战(5)-Feign应用通信_微服务_17
SpringCloud微服务实战(5)-Feign应用通信_微服务_18

SpringCloud微服务实战(5)-Feign应用通信_微服务_19
SpringCloud微服务实战(5)-Feign应用通信_微服务_20
SpringCloud微服务实战(5)-Feign应用通信_微服务_21

  • 再看看其负载均衡策略
    SpringCloud微服务实战(5)-Feign应用通信_微服务_22
    SpringCloud微服务实战(5)-Feign应用通信_微服务_23
    负载均衡请求
    SpringCloud微服务实战(5)-Feign应用通信_微服务_24
    SpringCloud微服务实战(5)-Feign应用通信_微服务_25
    的确是轮询请求
    SpringCloud微服务实战(5)-Feign应用通信_微服务_26
    SpringCloud微服务实战(5)-Feign应用通信_微服务_27
    为了检验是否为轮询,在此打断点
    SpringCloud微服务实战(5)-Feign应用通信_微服务_28
    SpringCloud微服务实战(5)-Feign应用通信_微服务_29
    如果希望使用其他负载均衡规则该咋办呢,看官网文档
    SpringCloud微服务实战(5)-Feign应用通信_微服务_30
    SpringCloud微服务实战(5)-Feign应用通信_微服务_31
    SpringCloud微服务实战(5)-Feign应用通信_微服务_32
    SpringCloud微服务实战(5)-Feign应用通信_微服务_33
Feign的使用

Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便 要使用Feign创建一个界面并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并使用Spring Web中默认使用的HttpMessageConverters。Spring Cloud集成Ribbon和Eureka以在使用Feign时提供负载均衡的http客户端。

如何加入Feign

  1. 要在您的项目中包含Feign,请使用组org.springframework.cloud和工件ID spring-cloud-starter-openfeign的启动器
    SpringCloud微服务实战(5)-Feign应用通信_微服务_34

  2. 在启动类添加注解@EnableFeignClients
    可以在@EnableFeignClients属性defaultConfiguration中以与上述相似的方式指定默认配置
    不同之处在于,此配置将适用于所有feigh客户端
    SpringCloud微服务实战(5)-Feign应用通信_微服务_35
    调用商品服务的目标接口
    SpringCloud微服务实战(5)-Feign应用通信_微服务_36

  3. 声明调用的服务接口方法

  • @FeignClient
    name属性为某所需调用的某个服务的接口
    @FeignClient注释中,String值(以上“存储”)是一个任意的客户端名称,用于创建Ribbon负载平衡器,还可以使用url属性(绝对值或只是主机名)指定URL。应用程序上下文中的bean的名称是该接口的完全限定名称。要指定自己的别名值,可以使用@FeignClient注释的qualifier值。
    SpringCloud微服务实战(5)-Feign应用通信_微服务_37

  • 声明式REST客户端(伪RPC )

  • 采用了基于接口的注解

6 获取商品列表(Feign)

SpringCloud微服务实战(5)-Feign应用通信_微服务_38
SpringCloud微服务实战(5)-Feign应用通信_微服务_39
SpringCloud微服务实战(5)-Feign应用通信_微服务_40
SpringCloud微服务实战(5)-Feign应用通信_微服务_41
SpringCloud微服务实战(5)-Feign应用通信_微服务_42
因为参数使用了 RequestBody 注解,所以需 POST 请求
SpringCloud微服务实战(5)-Feign应用通信_微服务_43
SpringCloud微服务实战(5)-Feign应用通信_微服务_44
SpringCloud微服务实战(5)-Feign应用通信_微服务_45
SpringCloud微服务实战(5)-Feign应用通信_微服务_46
SpringCloud微服务实战(5)-Feign应用通信_微服务_47

7 扣库存(Feign)

SpringCloud微服务实战(5)-Feign应用通信_微服务_48
SpringCloud微服务实战(5)-Feign应用通信_微服务_49
SpringCloud微服务实战(5)-Feign应用通信_微服务_50
由于缺失无参构造器
SpringCloud微服务实战(5)-Feign应用通信_微服务_51