Feign简介:

  1. Feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。Feign是基于Ribbon实现的工具。
  2. Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka。
  3. 在Spring Cloud中,Feign的使用:创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。且它支持Feign注解、JAX-RS注解和Spring MVC的注解。

Ribbon和Feign的区别:

Ribbon和Feign都是用于调用其他服务的,不过方式不同。

  1. 启动类使用的注解不同,Ribbon用的是@RibbonClient,Feign用的是@EnableFeignClients。
  2. 服务的指定位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。
  3. 调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。Feign则是在Ribbon的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建http请求。不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。

Feign较Ribbon的优点:

  1. Feign本身里面就包含有了Ribbon
  2. Feign自身是一个声明式的伪http客户端,写起来更加思路清晰和方便
  3. Fegin是一个采用基于接口的注解的编程方式,更加简便

使用Feign实现负载均衡:(注:代码接 Rest构建分布式微服务 一期的博客

springgateway负载均衡策略 修改_java

  1. 创建Fegin模块
  2. 配置pom.xml
  3. 创建application.yml配置文件
  4. 创建自定义Rest相关配置类ConfigBean
  5. 创建ProductClientService接口
  6. 创建ProductController_Feign
  7. 创建ProductConsumer_80_Fegin主启动类
  8. 测试

基本步骤:

  0. 增加一个数据库和一个服务提供者,将这个新的服务提供者连接到这个新增的数据库,测试时方便区分(实际开发中访问的是同一个数据库。

springgateway负载均衡策略 修改_spring_02

springgateway负载均衡策略 修改_Feign_03

  1. 创建名为microService-consumer-feign的Maven工程(jar包)

  2. 配置pom.xml

<dependencies>
        <!--依赖关系-->
        <dependency>
            <groupId>cn.zf</groupId>
            <artifactId>microService-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

  3. 在src/main/resources下创建application.yml配置文件

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    fetch-registry: true     #发现服务中  获得注册信息
    serviceUrl:
      defaultZone: http://eureka6001.com:6001/eureka,http://eureka6002.com:6002/eureka

  4. 在src/main/java下创建自定义Rest相关配置类ConfigBean

package cn.zf.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * Rest相关配置类访问RestFull的方法(url,requestMap,ResponseBean.class)
 */
@Configuration
public class ConfigBean {
    // 向容器中添加RestTemplate组件  直接通过该组件可以调用REST接口
    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

  5. 在src/main/java下创建ProductClientService接口

package cn.zf.springcloud.service;

import cn.zf.springcloud.entities.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@FeignClient(value = "MICROSERVICE-PRODUCT")
public interface ProductClientService {
    @RequestMapping(value = "/product/get/{id}",method = RequestMethod.GET)
    Product get(Long id);
    @RequestMapping(value = "/product/list",method = RequestMethod.GET)
    List<Product> list();
    @RequestMapping(value = "/product/add",method = RequestMethod.POST)
    boolean add(Product product);
}

  6. 在src/main/java下创建ProductController_Fegin

package cn.zf.springcloud.controller;

import cn.zf.springcloud.entities.Product;
import cn.zf.springcloud.service.ProductClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class ProductorController_Feign {
    @Autowired
    private ProductClientService service;
    @RequestMapping(value = "/consumer/product/add")
    public boolean add(Product product){
        return service.add(product);
    }
    @RequestMapping(value = "/consumer/product/get/{id}")
    public Product get(@PathVariable("id") Long id){
        return service.get(id);
    }
    @RequestMapping(value = "/consumer/product/list")
    public List<Product> list(){
        return service.list();
    }
}

  7. 创建ProductConsumer_80_Feign主启动类

package cn.zf.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients(basePackages = {"cn.zf.springcloud"})
@EnableEurekaClient   // 向注册中心进行注册
@SpringBootApplication
public class ProductConsumer_80_Feign {
    public static void main(String[] args) {
        SpringApplication.run(ProductConsumer_80_Feign.class,args);
    }
}

  8. 测试,先启动两个eureka注册中心的主启动类(两个注册中心顺序无所谓),再启动两个服务提供者的主启动类(两个服务提供者顺序无所谓),最后启动ProductConsumer_80_Feign服务消费者的主启动类

springgateway负载均衡策略 修改_Feign_04

springgateway负载均衡策略 修改_Feign_05


over~