分布式之LoadBalancer

一、LoadBalancer介绍

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

芯片顶级盛会Hotchips 2021年-苹果M1横空出世(附全套资料下载)

3.22 芯片顶级盛会Hotchips 2021年-未来芯片论坛及资料下载w0 提示&#xff1a;下载链接在文章最后。 HOTCHIPS是一个关于计算机体系结构和电子设计的会议&#xff0c;主要探讨芯片设计、存储器、能源效率、机器学习和人工智能等方面的发展。该会议每年都会召开一次&#xff0…

狂飙Linux平台,PostgreSQL16部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

SpringBlade error/list SQL 注入漏洞复现

0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade 框架后台 /api/blade-log/error/list路径存在SQL注入漏洞,攻击者除了可以利用 SQL 注入漏洞获取数…

Qt/QML编程之路:openglwidget和倒车影像的切换(43)

关于如何实现一个基于OpenGL的3d 图形,这个有很多专门的介绍,我在开发中遇到了这么一个问题: 如何实现一个倒车影像的video显示与一个3D物体显示的切换,因为开窗在同样的一个位置,如果车子倒车启动,则需要将原本显示3D的地方切换为视频图像的显示。 class testOpenGl : …

[SUCTF 2019]EasySQL --不会编程的崽

即使题目再简单&#xff0c;大佬的思维我还是跟不上哎。。。继续更新sql的第二天 看这个样子就知道是什么了----堆叠注入 老样子&#xff0c;先fuzz一下过滤了哪些关键字。基本如下 from flag handler prepare information_schema performance_schema等。先随便测试一下 吧。…

【io.net空投】交互攻略

一、io.net是什么 Io.net 是一个基于 Solana 的DePIN项目&#xff0c;为人工智能 (AI) 和机器学习 (ML) 公司聚合 GPU 资源。 Io.net 的例子&#xff0c;就是鼓励大家出借 GPU 算力&#xff0c;为 AI 或机器学习&#xff08;ML&#xff09;公司提供更低价、更有效率的算力资源…

jmeter 中用python 实现请求参数的随机

首先需要下载插件来让jmeter支持python脚本 下载地址&#xff1a;https://www.jython.org/download&#xff0c;下载完成后放到jmeter安装目录的lib文件夹下 放置完成后需要重启jmeter&#xff0c;添加JSR223 PreProcessor&#xff0c;Language下拉框中多2项 选择第一项&#…

Python的特性——跟老吕学Python编程

Python的特性——跟老吕学Python编程 Python的特性1.Python易学易用2.Python是解释型语言3.Python是交互式的4.Python是一种多范式语言5.Python的标准库6.Python是开源的7.Python是跨平台的8.用于GUI应用程序的Python9.Python的数据库连接10.Python是可扩展的11.Python拥有活跃…

在ubuntu上安装FastSufer【本机安装】

亲测:FastSurfer分割并重建一个大脑需要1个小时,而freeSurfer需要8个小时。确实很快! 这里我在网页端搭建了一个小的工具包,里面集成了经典的freeSurfer和较快的FastSurfer。如果你不想安装或者手头没有linux设备,您也可以直接从以下网址直接使用,跳过繁琐的安装步骤!!…

【论文阅读】VMamba:视觉状态空间模型

文章目录 VMamba:视觉状态空间模型摘要相关工作状态空间模型 方法准备状态空间模型离散化选择扫描机制 2D 选择扫描VMamba 模型整体结构VSS块 实验分析实验有效感受野输入尺度 总结 VMamba:视觉状态空间模型 摘要 受最近提出的状态空间模型启发&#xff0c;我们提出了视觉状态…

软件测试APP完整测试作业流程(附流程图),公司级软件测试流程化办公

目录 1. 概述 2. 软件测试流程 3. 软件测试周期人员活动图 4. 总结 1. 概述 1.1 目的 有效的保证软件质量&#xff1b; 有效的制定不同测试类型&#xff08;软件系统测试、音频主观性测试、Field Trial、专项测试、自动化测试、性 能测试、用户体验测试&#xff09;的软件…

BUUCTF---[MRCTF2020]你传你呢1

1.题目描述 2.打开题目链接 3.上传shell.jpg文件&#xff0c;显示连接成功&#xff0c;但是用蚁剑连接却连接不上。shell文件内容为 <script languagephp>eval($_REQUEST[cmd]);</script>4.用bp抓包&#xff0c;修改属性 5.需要上传一个.htaccess的文件来把jpg后缀…

C++ STL --stack 和queue,priority_queue

1. stack的介绍和使用 1.1 stack的介绍 https://cplusplus.com/reference/stack/stack/?kwstack 翻译: 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配…

嵌入式学习第二十七天!(TCP并发模型)

TCP并发模型&#xff1a; 1. TCP多线程模型&#xff1a; 缺点&#xff1a;创建线程会带来资源开销&#xff0c;能够实现的并发量比较有限。 2. IO模型&#xff1a; 1. 阻塞IO&#xff1a; 没有数据到来时&#xff0c;可以让任务挂起&#xff0c;节省CPU资源开销&#xff0c;提…

51单片机基础篇系列-LED灯点亮代码部分

&#x1f308;个人主页: 会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” #include<reg52.h> //包含单片机内部寄存器 void main() //&#xff08;&#xff09;{P10xfe;//1111 1110while(1); // } 上面是第一个 LED实验 #include<reg52.h>…

解码人工智能的幽默:理解其背后的误解与挑战

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

爬虫之矛---JavaScript基石篇5<JS混淆问题(1)>

前言: 随着现代JavaScript应用程序的复杂性增加,源代码的安全性成为开发者和企业关注的焦点之一。为了保护知识产权和防止代码被逆向工程,开发者采用了各种技术手段,其中一种重要的方法是混淆。 正文: 如何调试JS? 以chrome浏览器为例,在开发者工具里面,可以通过在source…

MacOS - 在 Mac 上自定义“访达”边栏(快捷方式)

将文件添加到边栏&#xff1a;按住 Command 键&#xff0c;然后将文件拖到“个人收藏”部分。如果没有看到“个人收藏”部分&#xff0c;请选取“访达” > “设置” > “边栏”&#xff0c;然后在“个人收藏”部分中选择至少一个项目。 将文件添加到“访达”边栏仅会创建…

WPF(2)命令绑定

效果是&#xff1a;当TextBox控件的Text属性为空时show按钮不可用&#xff0c;有值时show按钮可用 项目结构 界面代码 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sc…

Qt - 信号和槽

目录 一、信号 二、槽 三、信号和槽的使用 (一) 连接信号和槽 (二) 自定义槽 (三) 通过 Qt Creator生成信号槽代码 (四) 自定义信号 四、带参数的信号和槽 五、信号与槽的断开 六、Qt4版本信号与槽的连接 (一) Qt4版本信号与槽连接的优缺点 一、信号 在 Qt 中&…