[000-01-016].第05节:SpringCloud ->LoadBalancer- 负载均衡服务调用

我的后端学习大纲

SpringCloud学习大纲


1.Ribbon组件情况:

1.1.Ribbon是什么:

  • 1.Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具
    • 主要功能是提供客户端的软件负载均衡算法和服务调用
    • Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。
  • 2.简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。

1.2.Ribbon的替换方案:

  • 目前Ribbon不再维护,平替方案如下:
    在这里插入图片描述

2.spring-cloud-LoadBalancer概述:

2.1.spring-cloud-loadbalancer简单介绍:

a.spring-cloud-loadbalancer官网位置:

在这里插入图片描述

a. LB负载均衡(Load Balance)是啥:

  • 1.简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用),常见的负载均衡有软件Nginx,LVS,硬件 F5等
    在这里插入图片描述

b.spring-cloud-starter-loadbalancer组件是啥:

  • 1.Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器,它包含在SpringCloud-commons中用它来替换了以前的Ribbon组件
  • 2.相比较于Ribbon,SpringCloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient(WeClient是Spring Web Flux中提供的功能,可以实现响应式异步请求)

c.面试题:

loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别

  • 1.Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的
    在这里插入图片描述
  • 2.loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术
    在这里插入图片描述

3.spring-cloud-loadbalancer负载均衡解析:

3.1.负载均衡演示案例-理论:

a.架构说明:80通过轮训负载访问8001、8002、8003

在这里插入图片描述

b.LoadBalancer 在工作时分成两步:

  • 第一步:先选择ConsulServer从服务端查询并拉取服务列表,知道了它有多个服务(上图3个服务),这3个实现是完全一样的,默认轮询调用谁都可以正常执行。类似生活中求医挂号,某个科室今日出诊的全部医生,客户端你自己选一个。
  • 第二步:按照指定的负载均衡策略从server取到的服务注册列表中由客户端自己选择一个地址,所以LoadBalancer是一个客户端的负载均衡器。

3.2.负载均衡演示案例-实操:

a.官网参考如何使用:

在这里插入图片描述

在这里插入图片描述

b.按照8001拷贝后新建8002微服务:

  • 根据新建模块的步骤新建8002模块就可以,然后把8001中的实体类等拷贝过去即可

c.启动consul,将8001/8002启动后注册到微服务

  • 1.在consul中,我们已经配置了consul的持久化并且设置作为了windows的后台服务,所以如下方式启动:
    在这里插入图片描述

d.订单80模块修改pom文件并注册到consul,新增LoadBalance组件

  • 1.在客户端引入loadbalancer:
    在这里插入图片描述
<!--loadbalancer-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

e.订单80模块修改controller并启动80

package com.atguigu.cloud.controller;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * @auther zzyy
 * @create 2023-11-04 16:00
 */
@RestController
public class OrderController
{
    //public static final String PaymentSrv_URL = "http://localhost:8001";//先写死,硬编码

    public static final String PaymentSrv_URL = "http://cloud-payment-service";//服务注册中心上的微服务名称

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 一般情况下,通过浏览器的地址栏输入url,发送的只能是get请求
     * 我们模拟消费者发送get请求,but底层调用post方法,客户端消费者参数PayDTO可以不添加@RequestBody
     * @param payDTO
     * @return
     */
    @GetMapping("/consumer/pay/add")
    public ResultData addOrder(PayDTO payDTO)
    {
        return restTemplate.postForObject(PaymentSrv_URL + "/pay/add",payDTO,ResultData.class);
    }

    // 删除+修改操作作为家庭作业,O(∩_∩)O。。。。。。。

    @GetMapping("/consumer/pay/get/{id}")
    public ResultData getPayInfo(@PathVariable Integer id)
    {
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+id, ResultData.class, id);
    }

    @GetMapping(value = "/consumer/pay/get/info")
    private String getInfoByConsul()
    {
        return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/info", String.class);
    }
}

f.查看consul上的服务:

  • 1.查看控制台上后,订单服务和支付服务都在consul上注册了
    在这里插入图片描述

g.测试:

  • 1.当订单服务调用支付服务的时候,会轮询调用两个支付服务
    在这里插入图片描述
    在这里插入图片描述

3.3.负载均衡演示案例-小总结:

a.编码使用DiscoveryClient动态获取所有上线的服务列表

在这里插入图片描述

b.代码解释,修改80服务的Controller:

@Resource
private DiscoveryClient discoveryClient;

@GetMapping("/consumer/discovery")
public String discovery()
{
    List<String> services = discoveryClient.getServices();
    for (String element : services) {
        System.out.println(element);
    }

    System.out.println("===================================");

    List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
    for (ServiceInstance element : instances) {
        System.out.println(element.getServiceId()+"\t"+element.getHost()+"\t"+element.getPort()+"\t"+element.getUri());
    }

    return instances.get(0).getServiceId()+":"+instances.get(0).getPort();
}

c.结合前面实操,负载选择原理小总结:

  • 负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。
  • 1.List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");如:
    • List [0] instances = 127.0.0.1:8002
    • List [1] instances = 127.0.0.1:8001
  • 2.8001+ 8002 组合成为集群,它们共计2台机器,集群总数为2, 按照轮询算法原理:
  • 3.当总请求数为1时: 1 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001
  • 4.当总请求数位2时: 2 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002
  • 5.当总请求数位3时: 3 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001
  • 6.当总请求数位4时: 4 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002
    如此类推…

4.负载均衡算法:

4.1.默认的负载均衡算法是什么

  • 负载均衡默认是轮训算法

4.2.有几种负载均衡算法:

  • 1.默认有两种负载均衡算法:
    在这里插入图片描述

4.3.算法切换:

  • 1.从默认的轮训算法切换到随机算法,修改ResTemplateConfig
@Configuration
@LoadBalancerClient(
//下面的value值大小写一定要和consul里面的名字一样,必须一样
value = "cloud-payment-service",configuration = RestTemplateConfig.class)
public class RestTemplateConfig
{
    @Bean
    @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,                                                        LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

4.4.测试:

在这里插入图片描述

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值