Spring Cloud LoadBalancer原理讲解及自定义负载均衡器
Spring Cloud LoadBalancer原理
LoadBalancerClient作为负载均衡客户端,用于进行负载均衡逻辑,从服务列表中选择出一个服务地址进行调用,其内部方法为下图显示:

(图1-1)
在LoadBalancerClient种存在两个execute()方法,均是用来执行请求的,reconstructURI()是用来重构URL。对于LoadBalancerClient在Spring Cloud LoadBalancer中实现类则是BlockingLoadBalancerClient。BlockingLoadBalancerClient存在两个choose()方法,其实现的是图1-1中的ServiceInstanceChooser接口种的两个choose()方法(图1-2):

(图1-2)
在上述图片中通过通过工厂类LoadBalancerClientFactory获取具体的负载均衡器实例,后面的loadBalancer.choose(request)调用(图1-3)接口choose()方法实现根据负载均衡算法选择下一个服务器完成负载均衡。

(图1-3)
图1-3可以看出ReactorLoadBalancer接口继承ReactiveLoadBalancer接口,ReactorLoadBalancer接口后续又被ReactorServiceInstanceLoadBalancer继承且其实现了两个方法,分别是:RandomLoadBalancer(随机负载均衡器)和RoundRobinLoadBalancer(轮询负载均衡器)。

(图1-4)
LoadBalancer自定义负载均衡器
根据图1-4类图显示,我们只需要在自定义配置轮询方法时重定义ReactorServiceInstanceLoadBalancer接口即可,如下例子:
@Configuration
public class MyLoadBalancerConfig {
@Bean
public ReactorServiceInstanceLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//返回随机轮询负载均衡方式
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
但是如果我们要自定义轮询算法该如何做呢?根据上面可以知道LoadBalancerClientFactory是创建客户机、负载均衡器和客户机配置实例的工厂。它根据客户端名称创建一个Spring ApplicationContext,并从中提取所需的bean(官方解释)。因此我们进入到LoadBalancerClientFactory类中:

(图1-5)
我们需要去实现它的子接口ReactorServiceInstanceLoadBalancer,因为去获取负载均衡器实例的时候,是通过去容器中查找ReactorServiceInstanceLoadBalancer类型的bean来实现的,参照RandomLoadBalancer我们进行仿写
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);
}
}
自定义配置类:
@Configuration
public class MyLoadBalancerConfig { // 参数 serviceInstanceListSupplierProvider 会自动注入
@Bean
public ReactorServiceInstanceLoadBalancer customLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
return new CustomRandomLoadBalancerClient(serviceInstanceListSupplierProvider);
}
}
在项目启动类上添加@LoadBalancerClient注解:name值一定要使用服务端配置的服务名(spring.application.name),通过configuration指定自定义的配置
@SpringBootApplication
@LoadBalancerClient(name = "myServer", configuration = MyLoadBalancerConfig.class)
public class BlockClientApplication { public static void main(String[] args) {
SpringApplication.run(BlockClientApplication.class, args);
}
}
以上内容参考借鉴总结得出,如有其他疑问可去一下地址查看详情:
https://blog.csdn.net/weixin_50518271/article/details/111449560
https://blog.csdn.net/qq_31142237/article/details/90486836
Spring Cloud LoadBalancer原理讲解及自定义负载均衡器的更多相关文章
- Spring Cloud 升级之路 - 2020.0.x - 6. 使用 Spring Cloud LoadBalancer (1)
本项目代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们使用 Spri ...
- SpringCloud升级之路2020.0.x版-22.Spring Cloud LoadBalancer核心源码
本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 经过上一节的详细分 ...
- 微服务生态组件之Spring Cloud LoadBalancer详解和源码分析
Spring Cloud LoadBalancer 概述 Spring Cloud LoadBalancer目前Spring官方是放在spring-cloud-commons里,Spring Clou ...
- Spring Cloud 升级之路 - 2020.0.x - 7. 使用 Spring Cloud LoadBalancer (2)
本项目代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们使用 Spri ...
- SpringCloud升级之路2020.0.x版-21.Spring Cloud LoadBalancer简介
本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们使用 Spri ...
- SpringCloud升级之路2020.0.x版-23.订制Spring Cloud LoadBalancer
本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们使用 Spri ...
- 拜托!面试请不要再问我Spring Cloud底层原理[z]
[z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...
- Spring Cloud底层原理(转载 石杉的架构笔记)
拜托!面试请不要再问我Spring Cloud底层原理 原创: 中华石杉 石杉的架构笔记 目录 一.业务场景介绍 二.Spring Cloud核心组件:Eureka 三.Spring Cloud核 ...
- spring cloud 2.x版本 Gateway自定义过滤器教程
前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...
- [转帖]Spring Cloud底层原理
拜托!面试不要再问我Spring Cloud底层原理 https://mp.weixin.qq.com/s/ZH-3JK90mhnJPfdsYH2yDA 毫无疑问,Spring Cloud 是目前微服 ...
随机推荐
- AntV L7 快速入门示例
1. 引言 L7 地理空间数据可视分析引擎是一种基于 WebGL 技术的地理空间数据可视化引擎,可以用于实现各种地理空间数据可视化应用.L7 引擎支持多种数据源和数据格式,包括 GeoJSON.CSV ...
- 六大云端 Jupyter Notebook 平台测评
有许多方法可以与其他人共享静态 Jupyter 笔记本,例如把它发布在 GitHub 上或通过 nbviewer 链接进行分享. 但是,如果接收人已经安装了 Jupyter Notebook 环境,那 ...
- @SuppressWarnings注解的使用
Java编译器在编译代码时,会产生一些安全警告信息.如果被@SuppressWarnings注解标记的元素,就可以告诉编译器抑制指定的警告. 先看看@SuppressWarnings注解在Java S ...
- 前端Vue自定义简单实用轮播图封装组件 快速实现轮播图
前端Vue自定义简单实用轮播图封装组件 快速实现轮播图, 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13153 效果图如下: ...
- 前端Vue自定义简单好用商品分类列表组件 侧边栏商品分类组件
前端Vue自定义简单好用商品分类列表组件 侧边栏商品分类组件 , 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13148 效果 ...
- C#使用企业微信群机器人推送生产数据
在日常的工作生产中,经常会有将将生产数据或者一些信息主动推送给相关的管理人员,我们公司在开发WMS系统时,为了仓库的储存安全,需要在危废品库存达到一定的储量时,自动通知仓管员去处理危废品,所以就需要程 ...
- 图书商城项目练习②后端服务Node/Express/Sqlite
本系列文章是为学习Vue的项目练习笔记,尽量详细记录一下一个完整项目的开发过程.面向初学者,本人也是初学者,搬砖技术还不成熟.项目在技术上前端为主,包含一些后端代码,从基础的数据库(Sqlite).到 ...
- SQL Sever 基础语法(增)
SQL Sever 插入(Insert)基础语法详解 在SQL中,向表中插入数据是最基础的,任何对数据处理的基础就是数据库有数据,对于SQL而言,向表中插入数据有多种方法,本文列举3种: (一) 标 ...
- Day11_Java_作业
1:递归那个兔子对数练习题 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?(使用递归去解决) 2:定义一个数组 ...
- Mysql基础4-数据查询
一.DQL介绍 DQL全称:Data Query Language(数据查询语言),用来查询数据库中表的记录. 关键字:select 二.DQL语法 select 字段列表 from 表名列表 whe ...