首页 > 技术文章 > SpringCloud Fegin 负载均衡

zhengzhaoxiang 2020-11-20 09:18 原文

Spring Cloud Ribbon 和 Spring Cloud Hystrix 在微服务中实现了客户端负载均衡的服务调用以及通过断路器来保护微服务应用。这两者作为基础工具类框架广泛地应用在各个微服务的实现中,不仅包括我们自身的业务类微服务,也包括一些基础设置类微服务(比如网关)。在实践中,这两个框架的使用几乎是同时出现的。那么是否有更高层次的封装来整合这两个基础工具,有就是Spring Cloud Fegin。基于 Netflix Feign 实现,除了整合上面两个强大的功能之外,还提供了一种声明式的 Web 服务客户端定义方式。

一、是什么


Fegin 是一个声明式 WebService客户端。使用 Fegin能让编写 Web Service 客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解即可,同时支持 JAX-RS标准的注解。Feign 也支持可拔插式的编码器和解码器。SpringCloud 对 Feign 进行了封装,使其支持了 Spring MVC 标准注解和 HttpMessageConverters(Http请求/响应与Java对象之间的转换)。Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡。可参考官网:https://github.com/OpenFeign/feign

大家目前都习惯面向接口编程,比如 WebService 接口,比如DAO接口,这个已经是规范。通过接口+注解获得调用服务应该是我们最喜欢的。所以就出现了Feign,它就可以满足上面的需求

二、能干什么


Fegin 指在使编写 Java Http客户端变的容易。使用 Ribbon+RestTemplate 时,利用 RestTemplate对http 请求的封装处理,形成了一套模板化的调用方式。但实际开发中,由于对服务的依赖调用可能不止一处,往往一个接口会被多出调用,所以通常会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以 Fegin 在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在 Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(以前是Dao接口上面添加Mapper 注解,现在是一个微服务接口上面标注一个 Feign 注解),即可完成服务提供方的接口绑定,简化使用 Spring Cloud Ribbon 时,自动封装服务调用客户的开发量。

三、案例


【1】根据 microservicecloud-consumer-dept-80(客户端) 创建 microservicecloud-consumer-dept-feign 微服务;
【2】修改 microservicecloud-consumer-dept-feign 模块的 pom.xml 文件中添加 feign;

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

【3】修改 microservicecloud-api 工程(公共的工程,相当于common,其他的子系统也可以调用此接口)
   ①、修改 pom.xml

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

   ②、在公共 microservicecloud-api 模块添加 DeptClientService 接口,并添加接口方法,这些方法与提供者的接口一模一样。同时在客户端添加  @FeignClient 注解。value=服务提供者暴露的名称,fallbackFactory=

@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 clear;
  ④、maven install;

【4】microservicecloud-consumer-dept-feign 工程修改 Controller,添加上一步新建的 DeptClientService 接口;

@RestController
public class DeptController_Consumer{
    @Autowired
    private DeptClientService service;

    @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);
    }
}

【5】microservicecloud-consumer-dept-feign 工程修改主配置类,通过 @EnableFeignClients 注解开启 Spring Cloud Feign 的支持功能。

@EnableFeignClients(basePackages= {"com.zzx.springcloud"})
public class DeptConsumer80_Feign_App
{

四、请求压缩


Spring Cloud Feign 支持对请求和响应进行 GZIP 压缩,以减少通信过程中的性能损耗。我们只需两个参数设置,就能开启请求于响应的压缩功能:

feign.compression.request.enabled=true
feign.compression.response.enabled=true

同时,我们还能对请求压缩做一些更细致的配置,比如压缩的请求数据类型,并设置请求压缩的大小下限,只有超过这个大小才会对其进行压缩:

feign.compression.request.enabled=true
#下面两个其实也是它的默认值
feign.compression.request.mime-type=text/xml,application/xml,application/json
feign.compression.request.min-request.size=2048

五、 日志配置


Spring Cloud Feign 在构建被 @FeignClient 注解修饰的客户端时,会为每一个客户端都创建一个 feign.Logger 实例,我们可以利用该日志对象的 DEBUG 模式来帮组分析 Feign 的请求细节。可以在 application.yml 配置文件中使用 logging.level.<FeignClient> 的参数配置格式来开启指定 Feign 客户端的 DEBUG 日志,其中 <FeignClient> 为 Feign 客户端定义接口的完整路径,比如:

Logging.level.com.zzx.springcloud.DeptClientService=DEBUG

这样还不够,由于 Feign 客户端默认的 Logger.Level 对象定义为 NONE 级别,该级别不会记录任何 Feign 调用过程的信息,所以我们需要调整它的级别,针对全局的日志级别,可以在应用主类中直接加 Logger.Level 的 Bean 创建。也可以通过实现配置类来实现,然后在具体的 Feign 客户端来指定配置类以实现是否要调整不同的日志级别::

@configuration
public class FullLogConfiguration{
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

@FeignClient(name="",configuration=FullLogConfiguration.class)
public interface xxx{
}

对于 Feign 的 Logger 级别主要有下面4类,可根据实际需要进行调整使用:
【1】NONE:不记录任何信息;
【2】BASIC:仅记录请求方法、URL 以及相应状态码和执行时间;
【3】HEADERS:除了记录 BASIC 级别的信息之外,还会记录请求和响应的头信息;
【4】FULL:记录所有请求于响应明细,包括头信息、请求体、元数据等;

六、总结:Feign 集成了 Ribbon


利用 Ribbon维护了 MicroServiceCloud-Dept 的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与 Ribbon不同的是,通过 Feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。关于Feign 的熔断机制 fallback 在 Hystrix 中进行说明;
博客链接】:链接


 ----架构师资料,关注公众号获取----

推荐阅读