聊一下微服务框架SpringCloud和使用-Feign均衡负载 [第五篇]

聊一下微服务框架SpringCloud和使用-Feign均衡负载 [第五篇]

Scroll Down

完整源码-仅供参考

https://github.com/ChannD/SpringCloudDemo

翻译

image.png

大致概述

先上官网解释

  • 官网解释链接
  • [图示]
  • image.png
  • 含义 : Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。**Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
    **
  • 只需要创建一个接口,然后在上面添加注解即可。
  • Feign能干什么
    • Feign旨在使编写Java Http客户端变得更容易。
    • 前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。 所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可), 即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
  • 整理 : 之前我使用的Ribbon进行负载均衡, 功能很强大, 甚至可以自己定义算法, 那么Feign为什么要出现呢? 原因有多个
    • 大部分大家都可以接受直接调用我们的微服务来进行访问(如我们之前的一串代码如下)
    • 大部分人目前都习惯面向接口编程, 比如WebService接口, 比如我们的DAO接口, 这个已经形成了一种规范(1.微服务名字活动调用地址. 2.通过接口+注解, 获得我们调用的服务 ) 适应社区其他程序员提出的, 还是统一的面向接口编程的套路 这就出现了Feign
//    private static final String REST_URL_PREFIX = "http://localhost:8001";
    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

2. Feign使用步骤

1. 参考microservicecloud-consumer-dept-80

2. 新建microservicecloud-consumer-dept-feign

  • 可以将主类命名DeptConsumer80_Feign_App

3. microservicecloud-consumer-dept-feign工程pom.xml修改,主要添加对feign的支持[新增代码]

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

4. 修改microservicecloud-api工程

  • 修改POM[代码]
   <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-feign</artifactId>
   </dependency>
  • 新建DeptClientService接口并新增注解@FeignClient[完整代码]
package com.chann.springcloud.service;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.chann.springcloud.entities.Dept;

@FeignClient(value = "MICROSERVICECLOUD-DEPT")
public interface DeptClientService
{
    @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET)
    public Dept get(@PathVariable("id") long id);

    @RequestMapping(value = "/dept/list",method = RequestMethod.GET)
    public List<Dept> list();

    @RequestMapping(value = "/dept/add",method = RequestMethod.POST)
    public boolean add(Dept dept);
}


  • Maven构建一个项目

5. microservicecloud-consumer-dept-feign工程修改Controller,添加上一步新建的DeptClientService接口[完整代码]

package com.chann.springcloud.controller;

import com.chann.springcloud.entities.Dept;
import com.chann.springcloud.service.DeptClientService;
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 DeptController_Feign
{
    //如果有印象的话,上一篇中我们是用RestTemplet调用的接口,现在我们又回到了我们惯用的方式来调用接口了
    @Autowired
    private DeptClientService service = null;

    @RequestMapping(value = "/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id)
    {
        return this.service.get(id);
    }

    @RequestMapping(value = "/consumer/dept/list")
    public List<Dept> list()
    {
        return this.service.list();
    }

    @RequestMapping(value = "/consumer/dept/add")
    public Object add(Dept dept)
    {
        return this.service.add(dept);
    }
}




6. microservicecloud-consumer-dept-feign工程修改主启动类[完整代码]

package com.chann.springcloud;

import com.chann.myrule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages= {"com.chann.springcloud"})
@ComponentScan("com.chann.springcloud")
public class DeptConsumer80_Feign_App
{
    public static void main(String[] args)
    {
        SpringApplication.run(DeptConsumer80_Feign_App.class, args);

    }

}

7. 测试

  • 启动3个eureka集群
  • 启动3个部门微服务8001/8002/8003
  • 启动Feign自己启动
  • http://localhost/consumer/dept/list
  • (没出现问题的话会以Ribbon配置的算法的方式访问 db01 02 03)
  • Feign自带负载均衡配置项

8. 小总结

  • Feign通过接口的方法调用Rest服务(之前是Ribbon+RestTemplate)
  • 该请求发送给Eureka服务器(http://MICROSERVICECLOUD-
    DEPT/dept/list),
    通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。