5、深入LoadBalance

news2025/3/6 21:11:42

一、介绍

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器,抽象和实现,用来替代Ribbon(已经停更),

二、Ribbon和Loadbalance 对比

组件组件提供的负载策略支持负载的客户端
Ribbon随机 RandomRule
轮询 RoundRobinRule
重试 RetryRule
最低并发 BestAvailableRule
可用过滤 AvailabilityFilteringRule
响应时间加权重 ResponseTimeWeightedRule
区域权重 ZoneAvoidanceRule
Feign或openfeign、RestTemplate
Spring Cloud LoadbalancerRandomLoadBalancer 随机(高版本有,此版本没有RoundRobinLoadBalancer 轮询(默认)Ribbon 所支持的、WebClient

LoadBalancer 的优势主要是,支持响应式编程的方式异步访问客户端,依赖 Spring Web Flux 实现客户端负载均衡调用。

三、整合LoadBlance

注意如果是Hoxton之前的版本,默认负载均衡器为Ribbon,需要移除Ribbon引用和增加配置spring.cloud.loadbalancer.ribbon.enabled: false。

1、升级版本

Spring Cloud AlibabaSpring cloudSpring Boot
2.2.6.RELEASESpring Cloud Hoxton.SR92.3.2.RELEASE

2、移除ribbon依赖,增加loadBalance依赖

<!--nacos-服务注册发现-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
	<exclusions>
		<!--将ribbon排除-->
		<exclusion>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
		</exclusion>
	</exclusions>
</dependency>


<!--添加loadbalanncer依赖, 添加spring-cloud的依赖-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

四、自定定义负载均衡器

package com.msb.order.loadbalance;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.reactive.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.reactive.Request;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Random;

public class CustomRandomLoadBalancerClient implements ReactorServiceInstanceLoadBalancer {
 
    // 服务列表
    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
 
    public CustomRandomLoadBalancerClient(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }
 
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
        return supplier.get().next().map(this::getInstanceResponse);
    }
 
    /**
     * 使用随机数获取服务
     * @param instances
     * @return
     */
    private Response<ServiceInstance> getInstanceResponse(
            List<ServiceInstance> instances) {
        System.out.println("进来了");
        if (instances.isEmpty()) {
            return new EmptyResponse();
        }
 
        System.out.println("进行随机选取服务");
        // 随机算法
        int size = instances.size();
        Random random = new Random();
        ServiceInstance instance = instances.get(random.nextInt(size));
 
        return new DefaultResponse(instance);
    }
}
@EnableDiscoveryClient
@SpringBootApplication
// 设置全局负载均衡器
@LoadBalancerClients(defaultConfiguration = {CustomRandomLoadBalancerClient.class})
// 指定具体服务用某个负载均衡
//@LoadBalancerClient(name = "msb-stock",configuration = CustomRandomLoadBalancerClient.class)
//@LoadBalancerClients(
//        value = {
//                @LoadBalancerClient(value = "msb-stock",configuration = CustomRandomLoadBalancerClient.class)
//        },defaultConfiguration = LoadBalancerClientConfiguration.class
//)
public class OrderApplication {

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

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

五、重试机制

spring:
  cloud:
    loadbalancer:
      #以下配置为LoadBalancerProperties 配置类
      clients:
        #default 表示去全局配置,如要针对某个服务,则填写毒地应的服务名称即可
        default:
          retry:
            enbled: true
            #是否有的的请求都重试,false表示只有GET请求才重试
            retryOnAllOperation: true
            #同一个实例的重试次数,不包括第一次调用:比如第填写3 ,实际会调用4次
            maxRetriesOnSameServiceInstance: 3
            #其他实例的重试次数,多节点情况下使用
            maxRetriesOnNextServiceInstance: 0

六、源码分析

1、猜测源码的实现

我们这里是给RestTemplate增加了@LoadBalanced就实现了负载均衡,我们学习Ribbon的时候是也是在RestTemplate上加了@LoadBalanced也实现了负载均衡,当时我们说RestTemplate上面有个扩展点ClientHttpRequestInterceptor, 我们Ribbon通过LoadBalancerInterceptor实现了这个扩展点,将msb-stock替换为 192.168.0.3:8003,如果所示:通过LoadBalancerClient 的实现类 RibbbonLoadBalancerClient 实现负载

image.png

那我们现在我们想LoadBalancer是不是也是同样的功能呢? 我们发现LoadBalancerClient 只有一个实现类是BlockingLoadBalancerClient

image.png

这是我们大概的猜想,他应该和我们的Ribbon的整体逻辑差不多

2、初始化过程

依旧是以前的逻辑找自动装配类,进入我们spring-cloud-starer-loadbalnecer:2.2.6.REALEAS 查找spring.factories,我们发现里面并没有对应spring.factories,这说明的这个starter只是起到jar管理的作用(查看的mybatis和SpringBoot整合的源码的话,会发现也是这样),所以我们进入pom中会发现应该是在spring-cloud-loadbalancer里面。

image.png

我们分析这里自动配置类BlockingLoadBalancerClientAutoConfiguration和我们刚才分析的BlockingLoadBalancerClient前边名称一样,那这个应该是我们重点分析的自动配置类

进入BlockingLoadBalancerClientAutoConfiguration 你会发现这里和Ribbon中的配置相似,都是在LoadBalancerAutoConfiguration之前

image.png

而LoadBalancerAutoConfiguration和我们将Ribbon中的配置是一样的,如下:

image.png

在BlockingLoadBalancerClientAutoConfiguration中我们看到一个重要的类BlockingLoadBalancerClient,这个类在前面我们分析过,通过他我们进行的负载均衡,里面有个参数是LoadBalancerClientFactory,这个参数我们可以想起我们讲解Ribbon中的SpringClientFactory,那哪里创建的他呢?

image.png

我们全文搜索会发先:在 LoadBalancerAutoConfiguration里面,这个类注意是在loadbalance包下和上面我们加载的LoadBalancerAutoConfiguration不是一个

image.png

对应加载配置和顺序如下:

image.png

3、获取负载均衡器

RestTemplate发送请求一定经过LoadBalancerInterceptor,中的intercept方法,这里loadBalancer是BlockingLoadBalancerClient

image.png

这里获取负载均衡器

image.png

image.png

image.png

这里就是从上面文中获取负载均衡器:RoundRobinLoadBalancer

4、获取实例

image.png

掉用RoundRobinLoadBalancer.choose方法

image.png

image.png

利用求余的方式选择一个实例,看到这我们发现实例列表已经获取到了,那什么时候获取到的呢?

5、获取服务实例列表

我们的服务列表是作为ServiceInstanceListSupplier的一个属性,那我们需要看在哪里创建的这个类:

image.png

在LoadBalancerClientConfiguration创建对应的类ServiceInstanceListSupplier

image.png我们看他withDiscoveryClient方法:

image.png

在DiscoveryClientServiceInstanceListSupplier构造方法里面:

image.png

image.png

image.png

image.png

6、进行调用

image.png

image.png

这个request前面已经构建出来

image.png

image.png

重构URL

image.png

在下面进行执行

image.png

image.png

image.pngimage.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css的应用详解

一、css的应用 1、在标签上的应用 <img style"height: 500px; width:500px" src"/static/1.jpg" /> <div style"color:red;">祖国</div>将样式直接写在标签上 2、在head标签中应用style标签 <!DOCTYPE html> <ht…

IntelliJ IDEA 下载安装教程(详细图文)

IntelliJ IDEA 下载安装教程&#xff08;详细图文&#xff09; 简介 IDEA 全称 IntelliJ IDEA&#xff0c;是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具 下载安装 ► 官网地址&#xff1a;https://www.jetbrains.com/idea ► 快速下载 (官方安装…

【SQL】保姆级教程:MySQL配置全过程 编辑器DBeaver的安装配置

MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系统)应用软件之一。 文章目录 一、什么是数据库&#xff1f;二、RDBMS 术语三、MySQL 安装四、安装DBeaver五、dbea…

Python异步编程框架asyncio使用方法

asyncio概念 Python异步编程框架asyncio是Python 3.4及以上版本提供的一个标准库&#xff0c;用于编写异步IO并发代码。asyncio提供了一种基于协程的高效的方式来实现异步编程&#xff0c;它可以使我们在单线程中处理大量的并发IO操作&#xff0c;提高程序的并发能力和性能。 …

输入 jar cvf 后指令提示‘jar‘ 不是内部或外部命令,也不是可运行的程序

输入 jar cvf 后指令提示jar 不是内部或外部命令&#xff0c;也不是可运行的程序 一堆说jdk系统环境配置的文章&#xff0c;我都看哭了&#xff0c;还好有这位老兄拯救了我&#xff01;&#xff01;&#xff01;献上地址 https://www.cnblogs.com/wadezhou/p/16647474.html 我输…

AI图像生成无需API开发连接集简云数据表,实现快速增强图片分辨率

1 场景描述 当设计接到一个需求时&#xff0c;按照常规的工作安排&#xff0c;从对接需求到最后完成效果图最短时间都要在5天左右&#xff0c;如果遇到高要求的客户或领导&#xff0c;后期还需要在电脑上进一步调整细节&#xff0c;一张成片起码要花上数小时时间去完成。 而人工…

Python_paramiko_与linux交互

一、基础功能介绍 # codingutf-8 import paramiko from time import sleep# 建立通信 transport paramiko.Transport((192.168.0.7, 22)) print(transport) # <paramiko.Transport at 0x5745ed0 (unconnected)># 建立连接 transport.connect(usernameroot, password1…

redis穿透问题

1.概述 一个热点数据在高并发情况下过期时间到了&#xff0c;会导致大量流量查询redis为null&#xff0c;进而请求数据库进行更新数据&#xff0c;从流量上来说请求打到了数据库上&#xff0c;这种情况可能会造成mysql服务崩溃。 2. 解决方式之一&#xff08;加锁解决之本地锁&…

机器人制作开源方案 | Delta型腿机器狗实现原地动作

1. 功能说明 本文示例将实现R322样机Delta型腿机器狗原地摆臂、原地圆形摆动、原地蹲起、原地踏步的功能。 原地摆臂 原地圆形摆动 原地蹲起 原地踏步 2. 电子硬件 本实验中采用了以下硬件&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09; 扩展板 Bigf…

pyspark随记

1、spark读取文件 #1.spark 读取csv custid_df spark.read.format("csv").\option("sep", ",").\option("header", True).\option("encoding", "utf-8").\schema("custid STRING").\load("/tmp/…

SQL聚合函数和窗口函数

1.创建表格插入数据 DROP TABLE IF EXISTS 学生; create table 学生 (student_id INT PRIMARY KEY,gender TEXT,city TEXT,a_score FLOAT(2),b_score FLOAT(2),weight FLOAT(2) )engineinnodb;INSERT INTO 学生 VALUES (001,female,xiameng,90.6,110.87,50.34), (002,male,gua…

应用程序发生异常,6个方法轻松解决!

“用电脑的时候大家有没有遇到过应用程序异常的情况呀&#xff01;刚刚突然遇到这种情况不知道应该怎么解决&#xff0c;请大家帮帮我吧&#xff01;” 应用程序发生异常是在使用电脑时常见的问题之一。当应用程序无法正常运行或突然崩溃时&#xff0c;它会显示一个错误消息或弹…

港联证券-尾盘集合竞价拉升意味着什么意思?

在股票市场中&#xff0c;尾盘集合竞价是指每个交易日的最后几分钟&#xff0c;即下午14:57到3:00之间的交易。在这段时间内&#xff0c;所有股票的买卖都将以竞价的方式进行&#xff0c;最终价格以最高买价与最低卖价的平均值确定&#xff0c;成交量也将作为当日的收盘价和成交…

Qt音视频开发47-文字和图片水印(可存储到MP4中)

一、前言 近期花了两周时间闭门啃硬骨头&#xff0c;主要就解决三个问题&#xff08;音视频同步存储和推流、图片水印并将水印信息存储到文件或者推流、rtsp推流&#xff09;&#xff0c;这三个问题困扰了很多年&#xff0c;以至于找遍了网络和翻遍ffplay代码以及ffmpeg示例的…

【ceph】存储池pg个数如何设置

存储池pg个数如何设置 参考官方文档说明&#xff1a;https://old.ceph.com/pgcalc/参数说明TargePGs per OSD&#xff1a;每个OSD的pg数OSD#存储池包含osd个数%Data存储池写入数据占总OSD容量百分比Size存储池冗余数

Selenium 报表自动化测试——黑盒测试篇

目录 前言&#xff1a; 背景 需求 分析 解决思路 解决方案 测试流程图 实现的功能 用例代码 两种测试方式 随机测试 指定测试 总结 前言&#xff1a; Selenium是一个广泛使用的自动化测试工具&#xff0c;用于Web应用程序的测试。它提供了一组功能强大的API&…

【CCF推荐】1区TOP刊,稳定检索29年,仅17天见刊,7月26即将截稿~

本期小编给大家推荐的是一本1区计算机科学类SCI. 该期刊为CCF推荐TOP刊&#xff0c;是计算机科学领域高质量期刊&#xff0c;隶属于世界前三出版社旗下。 发表与数字孪生、物联网、服务计算、智能计算、大数据、云计算、网络服务等方向相关或结合研究的高质量原创文章。 在…

关于SpringMVC的面试题

一、SpringMVC执行流程知道吗&#xff1f; 前后端分离开发环境下&#xff08;接口开发、异步请求&#xff09;&#xff1a; ①用户端发送请求到前端控制器DispatcherServlet ②DispatcherServlet收到请求调用HandlerMapping ③HandlerMapping找到具体的处理器&#xff0c;生…

itheima苍穹外卖项目学习笔记--Day8: 用户下单 / 微信支付

Day8&#xff1a;用户下单、微信支付 Day8&#xff1a;用户下单、微信支付a. 用户下单b. 微信支付 Day8&#xff1a;用户下单、微信支付 a. 用户下单 创建OrderController并提供用户下单方法&#xff1a; /*** 用户下单* param ordersSubmitDTO* return*/ PostMapping("…

数字信号转模拟信号PWM脉宽调制信号输入隔离变送器1Hz~10KHz转0-5V/0-10V4-20mA

主要特性: >>精度等级&#xff1a;0.1级。产品出厂前已检验校正&#xff0c;用户可以直接使用 >>辅助电源&#xff1a;8-32V 宽范围供电 >>PWM脉宽调制信号输入: 1Hz~10KHz >>输出标准信号&#xff1a;0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等&…