SpringCloud-负载均衡(Ribbon/OpenFeign)

本文最后更新于2023.05.06-10:39,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥

什么是负载均衡?

负载均衡(Load-balance LB),指的是将用户的请求平摊分配到各个服务器上,从而达到系统的高可用。常见的负载均衡软件有Nginx、lvs等。

为什么要做负载均衡?

  1. 不做负载均衡,可能导致某台机子负荷太重而挂掉;
  2.   导致资源浪费,比如某些机子收到太多的请求,肯定会导致某些机子收到很少请求甚至收不到请求,这样会浪费系统资源。

实现的均衡的方式

  • Ribbon
  • Feign

什么的Ribbon?

Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具。

Netflix Ribbon 是 Netflix 公司发布的开源组件,其主要功能是提供客户端的负载均衡算法和服务调用。Spring Cloud 将其与 Netflix 中的其他开源服务组件(例如 Eureka、Feign 以及 Hystrix 等)一起整合进 Spring Cloud Netflix 模块中,整合后全称为 Spring Cloud Netflix Ribbon。

Ribbon 是 Spring Cloud Netflix 模块的子模块,它是 Spring Cloud 对 Netflix Ribbon 的二次封装。通过它,我们可以将面向服务的 REST 模板(RestTemplate)请求转换为客户端负载均衡的服务调用。

Ribbon 是 Spring Cloud 体系中最核心、最重要的组件之一。它虽然只是一个工具类型的框架,并不像 Eureka Server(服务注册中心)那样需要独立部署,但它几乎存在于每一个使用 Spring Cloud 构建的微服务中。

Spring Cloud 微服务之间的调用,API 网关的请求转发等内容,实际上都是通过 Spring Cloud Ribbon 来实现的,包括后续我们要介绍的 OpenFeign 也是基于它实现的。

Ribbon内置负载均衡算法

1、 RoundRobinRule
轮询策略:Ribbon 默认采用的策略。若经过一轮轮询没有找到可用的provider,其最多轮询 10 轮(代码中写死的,不能修改)。若还未找到,则返回 null。

2、RandomRule
随机策略:从所有可用的 provider 中随机选择一个。

3、RetryRule
重试策略:先按照 RoundRobinRule 策略获取 server,若获取失败,则在指定的时限内重试。默认的时限为 500 毫秒。

4、BestAvailableRule
最可用策略:选择并发量最小的 provider,即连接的消费者数量最少的provider。其会遍历服务列表中的每一个server,选择当前连接数量minimalConcurrentConnections 最小的server。

5、AvailabilityFilteringRule
可用过滤算法:该算法规则是过滤掉处于熔断状态的 server 与已经超过连接极限的server,对剩余 server 采用轮询策略。

Ribbon和RestTemplate实现服务调用

1,搭建微服务项目以及服务注册与发现看这篇文章

SpringCloud-服务注册与发现(Eureka)
本文最后更新于2023.05.06-10:39,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥。什么是服务治理? springcloud封装了Netflix公司开发的Eur……

2,在启动类添加@EnableDiscoveryClient 并添加RestTempLate交由spring容器进行管理代码如下:

package com.client.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

3,服务调用

package com.client.consumer.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Program: springcloud
 * @ClassName ConsumerController
 * @Author: liutao
 * @Description: 消费者接口
 * @Create: 2023-03-01 20:04
 * @Version 1.0
 **/
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

//    利用ribbon+resttemplate进行服务调用
    @RequestMapping("/get")
    public String get(){
        return restTemplate.getForObject("http://SERVICE-PROVIDER/provider/get",String.class);
    }

}

4,启动服务并输入访问地址 http://localhost/consumer/get 效果如下:

什么是Feign?

Netflix Feign 是 Netflix 公司发布的一种实现负载均衡和服务调用的开源组件。Spring Cloud 将其与 Netflix 中的其他开源服务组件(例如 Eureka、Ribbon 以及 Hystrix 等)一起整合进 Spring Cloud Netflix 模块中,整合后全称为 Spring Cloud Netflix Feign。
 
Feign 对 Ribbon 进行了集成,利用 Ribbon 维护了一份可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。

Feign 是一种声明式服务调用组件,它在 RestTemplate 的基础上做了进一步的封装。通过 Feign,我们只需要声明一个接口并通过注解进行简单的配置(类似于 Dao 接口上面的 Mapper 注解一样)即可实现对 HTTP 接口的绑定。

通过 Feign,我们可以像调用本地方法一样来调用远程服务,而完全感觉不到这是在进行远程调用。

Feign 支持多种注解,例如 Feign 自带的注解以及 JAX-RS 注解等,但遗憾的是 Feign 本身并不支持 Spring MVC 注解,这无疑会给广大 Spring 用户带来不便。

2019 年 Netflix 公司宣布 Feign 组件正式进入停更维护状态,于是 Spring 官方便推出了一个名为 OpenFeign 的组件作为 Feign 的替代方案。

OpenFeign实现服务间的调用

1,搭建微服务项目以及服务注册与发现看这篇文章

SpringCloud-服务注册与发现(Eureka)
本文最后更新于2023.05.06-10:39,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥。什么是服务治理? springcloud封装了Netflix公司开发的Eur……

2,在consumer 的pom中添加依赖

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

3,在启动类加上@EnableFeignClients 注解如下:

package com.client.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

3,创建一个service文件夹并创建一个名为ProviderService的接口不用写实现类定义一个客户端(注意@FeignClient只能用于接口

package com.client.consumer.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Program: springcloud
 * @ClassName ProviderService
 * @Author: liutao
 * @Description: service
 * @Create: 2023-03-01 21:08
 * @Version 1.0
 **/

@FeignClient("SERVICE-PROVIDER")
public interface ProviderService {
    @RequestMapping("/provider/get")
    String get();
}

4,服务调用

package com.client.consumer.web;

import com.client.consumer.service.ProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Program: springcloud
 * @ClassName ConsumerController
 * @Author: liutao
 * @Description: 消费者接口
 * @Create: 2023-03-01 20:04
 * @Version 1.0
 **/
@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private ProviderService providerService;

//    使用OpeFeign
    @RequestMapping("/getInfo")
    public String getInfo(){
        return providerService.get();
    }

}

5,启动consumer和provider服务。输入访问地址 http://localhost/consumer/getInfo效果如下

结尾

好快又到了和大家说再见的时候。如果觉得此文章对你有用一定不要点赞,评论哦!!!

下篇文章我们将讲的是服务熔断(Hystrix)敬请期待!!!

阅读剩余
THE END