SpringCloud Alibaba 负载均衡你还不懂?

共 4888字,需浏览 10分钟

 ·

2021-05-14 12:25

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

概述

负载均衡是分布式架构的重点,负载均衡机制决定着整个服务集群的性能与稳定。

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行

负载均衡解决的是将一个客户端的流量以某种符合最大化资源利用率的方式均摊到服务端所提供的所有实例上的问题。在这个问题的场景中,后端服务的实例是通过水平扩展的方式来提供高可用的。

负载均衡分类

在微服务架构中,负载均衡是必须使用的技术,通过它来实现系统的高可用、集群扩容等功能。负载均衡可以分为两种:服务端负载均衡和客户端负载均衡。

1、服务器负载均衡

通常所说的负载均衡指服务器负载均衡,由服务端来决定调用哪个节点,可通过硬件设备或软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等,类似的架构图如下:

原理:

通过硬件或软件实现负载均衡均会维护一个服务端清单,利用心跳检测等手段进行清单维护,保证清单中都是可以正常访问的服务节点。当用户发送请求时,会先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法(轮训、随机、加权轮训)从可用的服务端列表中取出一台服务端的地址,接着进行转发,降低系统的压力

2、客户端负载均衡

客户端实际上是指服务调用者。在 SpringCloud 中调用者本身集成负载均衡,由调用者决定来调用哪个节点的服务,这就是客户端负载均衡。

SpringCloud Ribbon是基于客户端的负载均衡工具,它可以将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用。

原理:

Ribbon 维护了一个服务列表,如果服务实例注销或死掉,Ribbon 能够自行将其剔除。Ribbon 提供了客户端负载均衡的功能,Ribbon 利用从注册中心中读取到的服务信息列表(存储在本地即客户端中),在调用某个服务时,根据负载均衡算法直接请求到具体的微服务实例,常用的负载均衡算法有:轮循、随机、加权轮循、加权随机、地址哈希等方法。如下图是Ribbon负载均衡的流程图:

3、客户端和服务端负载均衡的区别

两者主要区分点在于服务清单的存放位置:在客户端负载均衡中,客户端会存储一份服务端清单,它是通过从注册中心进行抓取得到的,同时也需要对此进行维护;而在服务端负载均衡中,服务端自己会维护一份服务端清单

Ribbon 简介

Spring Cloud Ribbon是一个基于 HTTP 和 TCP 协议客户端负载均衡工具,它基于Netflix Ribbon实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon 虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

1、负载均衡的策略
2、负载均衡策略的设置
3、负载均衡的常用接口

Ribbon 负载均衡的类型

在spring cloud微服务架构中,基本上每个拆分的微服务都会部署多个运行实例。每个服务多个实例,能够提高吞吐量和可用性,使得流量均匀分布,防止单台瓶颈,也避免单点故障。

Ribbon 维护了一个服务列表,服务列表以服务的应用名为区分,当调用某个服务名的服务时,Ribbon
会根据负载均衡算法直接请求到该服务名下某个具体的微服务实例。

因此负载均衡适用的同一微服务名下的微服务实例有两种类型:

1、不同工程具有同一服务名


上述两个不同的工程,因为具有相同的服务名 alibaba-server-hello,因此是属于同一服务名下的不同实例
除了应用名一样外,
被调用的服务名对应的各个工程实例的同一接口的访问地址应该也要相同
服务名在配置文件application.yml 以及Nacos配置文件中声明。

application.yml

Nacos 配置文件

2、同一工程部署在不同端口上

将某个工程部署在不同端口上,这种情况下不同服务实例除了端口不同外其他的配置都相同,因此具有相同的服务名,属于同一服务名下的不同实例
同一工程部署不同实例的做法如下:

给 alibaba-server-helloworld 工程添加第2个实例的流程如下:

(1)alibaba-server-helloworld 服务的配置文件中不能设置端口号

application.yml 文件

Nacos配置文件

因为 alibaba-server-helloworld 服务的每个实例只有端口号不同,所以在配置文件中不能设置端口号,否则每个实例的端口号将会相同,因而不能创建部署于不同端口的多实例。(配置文件的端口号设置优先于在 VM Options 中通过 -Dserver.port = xxxx 设置端口号)

(2)打开Edit Configurations

(3)点击“ + ”号,选择Spring Boot,添加实例
(4)填写实例名称、实例的主类以及实例的端口号

主类选择 alibaba-server-helloworld 服务的主类 WorldApplication;
在 VM options 中设置实例的端口号 
-Dserver.port = 8005

(5)点击 Apply 后,新的实例即可创建完成

能够看到 alibaba-server-helloworld 服务有两个分别运行在 8005 和 8006 端口的实例

(6)查看 Nacos 服务列表

能够看到在服务列表中 alibaba-server-helloworld 服务有两个实例

客户端负载均衡Ribbon使用

1、RestTemplate + Ribbon (使用同一工程不同端口类型)

(1)在 RestTemplate 配置类里面在注入 RestTemplate 的方法上面添加注解 @LoadBalanced 即可实现负载均衡

@LoadBalanced 原理:
RestTemplate在发送请求的时候会被ClientHttpRequestInterceptor拦截,LoadBalancerInterceptor是ClientHttpRequestInterceptor的实现类,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalancer。
@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。

@Component
public class RestTemplateConfig {
    @Bean
    @LoadBalanced  // 负载均衡注解
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

注:我们这里不需要添加Ribbon的依赖,因为 Nacos Client 包里面帮我们引入 Ribbon 相关的依赖

(2)controller 中多次调用 alibaba-server-helloworld 服务

@RestController
@Slf4j
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/diaoyong")
    public  String msg(){
        System.out.println("服务列表");
        List<ServiceInstance> list=discoveryClient.getInstances("alibaba-server-helloworld");
        System.out.println(list);
        String response = restTemplate.getForObject("http://alibaba-server-helloworld/hello/lhj/hello", String.class);
        return response;
    }
}

(3)调用 4 次 alibaba-server-helloworld 服务查看效果

可以发现两个实例分别调用两次,而且是轮流调用,也就是说 Ribbon 的默认负载均衡策略是轮循。

2、Feign(默认继承了Ribbon)

Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单。使用 Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解。Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,默认实现了负载均衡的效果。所以使用Feign无需任何操作就已经附带了Ribbon负载均衡。




版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/IT__learning/article/details/116540399





锋哥最新SpringCloud分布式电商秒杀课程发布

👇👇👇

👆长按上方微信二维码 2 秒





感谢点赞支持下哈 

浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报