当前位置: 首页 > news >正文

多机部署,负载均衡-LoadBalance

文章目录

  • 多机部署,负载均衡-LoadBalance
    • 1. 开启多个服务
    • 2. 什么是负载均衡
      • 负载均衡的实现
      • 客户端负载均衡
    • 3. Spring Cloud LoadBalance
      • 快速上手
        • 使用Spring Cloud LoadBalance实现负载均衡
        • 修改IP,端口号为服务名称
        • 启动多个服务
      • 负载均衡策略
        • 自定义负载均衡策略
      • LoadBalance原理

多机部署,负载均衡-LoadBalance

1. 开启多个服务

多复制两个服务,将服务全部启动起来

此时多次访问原来的接口,发现

调用的还是同一个

我们对代码进行修改:

@Service
public class OrderService {private static final Logger log = LoggerFactory.getLogger(OrderService.class);@Autowiredprivate OrderMapper orderMapper;@Resourceprivate DiscoveryClient discoveryClient;@Autowiredprivate RestTemplate restTemplate;private static AtomicInteger atomicInteger = new AtomicInteger(1);private static List<ServiceInstance> instances;@PostConstructpublic void init() {instances = discoveryClient.getInstances("product-service");}public  OrderInfo getOrderList(int orderId){OrderInfo orderInfo = orderMapper.getOrderList(orderId);int index = atomicInteger.getAndIncrement() % instances.size();EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(index);String url = instance.getUri() + "/product/getProduct?productId=" + orderInfo.getProductId();log.info(url);ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

通过轮询的方式去将请求均衡的分配到不同的实例上,这就是负载均衡

2. 什么是负载均衡

负载均衡是高并发,高可用系统必不可少的关键组件

当服务流量增大的时候,通常会采用增加机器的方式进行扩容,负载均衡就是用来在多个机器或者其他资源中,按照一定的规则合理分配负载,也就是负载均衡策略

负载均衡的实现

负载均衡分为服务端负载均衡和客户端负载均衡

服务端负载均衡

指的是在服务端进行负载均衡的算法分配

例如Nginx就是比较出名的服务端负载均衡器,请求会先到达Nginx负载均衡器,然后通过负载均衡算法,在多个服务器之间选择一个进行访问

客户端负载均衡

在客户端进行负载均衡的算法分配

就是将负载均衡的功能以库的方式集成到客户端,而不是由一台指定的负载均衡设备集中提供

比如Spring Cloud的Ribbon,请求发送到客户端,客户端从注册中心(比如Eureka)获取服务列表,在发送请求的时候通过负载均衡算法一个服务器,然后进行访问

但是Ribbon是Spring Cloud早期的默认实现,由于不维护了,现在最新版本的Spring Cloud 负载均衡集成的是Spring Cloud LoadBalance(Spring Cloud官方维护)

客户端负载均衡器和服务端负载均衡器的最大区别在于服务清单存储的位置

3. Spring Cloud LoadBalance

快速上手

使用Spring Cloud LoadBalance实现负载均衡

给RestTemplate这个Bean 添加 @LoadBalance注解

@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
修改IP,端口号为服务名称
@Service
public class OrderService {private static final Logger log = LoggerFactory.getLogger(OrderService.class);@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public  OrderInfo getOrderList(int orderId){OrderInfo orderInfo = orderMapper.getOrderList(orderId);String url = "http://product-service/product/getProduct?productId=" + orderInfo.getProductId();log.info(url);ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}
启动多个服务

进行6次访问

为了方便观察,我们在product-service里面加上日志

此时进行访问

可以看到请求被均匀的分布在3个实例上

负载均衡策略

负载均衡策略是一种思想,无论是哪种负载均衡,他们的负载均衡策略都是相似的.Spring Cloud LoadBalance仅支持两种负载均衡策略:轮询策略以及随机策略

  1. 轮询:轮询策略指的是服务器轮流处理用户的请求.这是一种实现最简单,也最常用的策略
  2. 随机选择:随机选择策略是指随机选择一个后端服务器来处理新的请求
自定义负载均衡策略

Spring Cloud LoadBalance默认的负载均衡策略是轮询策略.实现是RoundRobinLoadBalance

如果想使用随机的负载均衡策略:

  1. 定义随机算法对象,通过@Bean将其加载到Spring容器里面

这里我们使用Spring Cloud LoadBalancer提供的RandomLoadBalance

public class LoadBalanceConfig {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalance(Environment env, LoadBalancerClientFactory clientFactory) {String name = env.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(clientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

注意:不用@Configuration注释,要求这个类在组件扫描范围内

  1. 使用@LoadBalancerClieent或者@LoadBalancerClients注解在RestTemplate配置类上方,就可以实现对不同的服务提供方配置不同的客户端负载均衡算法策略
@LoadBalancerClient(name = "product-service",configuration = LoadBalanceConfig.class)
@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

其中,name表示该负载均衡策略对哪个服务生效(服务提供方),Configuration表示负载均衡策略

LoadBalance原理

LoadBalance的实现,主要是LoadBalanceInterceptor,这个类会对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,然后利用负载均衡算法得到真实的服务地址信息,替换服务Id


public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {private LoadBalancerClient loadBalancer;private LoadBalancerRequestFactory requestFactory;public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {this.loadBalancer = loadBalancer;this.requestFactory = requestFactory;}public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));}public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {URI originalUri = request.getURI();String serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));}
}

主要就是看intercept方法,拦截了用户的请求后,做了以下几件事:

  1. request.getURI()从请求中获取uri
  2. originalUri.getHost()从uri中获取路径的主机名,也就是服务Id
  3. loadBalancer.execute根据服务Id,进行负载均衡,并处理请求

我们继续看execute方法

public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
String hint = this.getHint(serviceId);
LoadBalancerRequestAdapter<T, TimedRequestContext> lbRequest = new LoadBalancerRequestAdapter(request, this.buildRequestContext(request, hint));
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = this.getSupportedLifecycleProcessors(serviceId);
supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onStart(lbRequest);
});
// 根据serviceId,和负载均衡策略,选择处理的服务
ServiceInstance serviceInstance = this.choose(serviceId, lbRequest);
if (serviceInstance == null) {supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onComplete(new CompletionContext(Status.DISCARD, lbRequest, new EmptyResponse()));});throw new IllegalStateException("No instances available for " + serviceId);
} else {return this.execute(serviceId, serviceInstance, lbRequest);
}
}
public <T> ServiceInstance choose(String serviceId, Request<T> request) {// 获取负载均衡器ReactiveLoadBalancer<ServiceInstance> loadBalancer = this.loadBalancerClientFactory.getInstance(serviceId);if (loadBalancer == null) {return null;} else {// 根据负载均衡算法,在列表中选择一个服务实例Response<ServiceInstance> loadBalancerResponse = (Response)Mono.from(loadBalancer.choose(request)).block();return loadBalancerResponse == null ? null : (ServiceInstance)loadBalancerResponse.getServer();}
}

相关文章:

多机部署,负载均衡-LoadBalance

文章目录 多机部署,负载均衡-LoadBalance1. 开启多个服务2. 什么是负载均衡负载均衡的实现客户端负载均衡 3. Spring Cloud LoadBalance快速上手使用Spring Cloud LoadBalance实现负载均衡修改IP,端口号为服务名称启动多个服务 负载均衡策略自定义负载均衡策略 LoadBalance原理…...

Hadoop安装与配置

一、Hadoop安装与配置 1、解压Hadoop安装包 找到hadoop-2.6.0.tar.gz,将其复到master0节点的”/home/csu”目录内&#xff0c;解压hadoop [csumaster0 ~]$ tar -zxvf ~/hadoop-2.6.0.tar.gz 解压成成功后自动在csu目录下创建hadoop-2.6.0子目录&#xff0c;可以用cd hadoo…...

一个自制的比较low的刷题软件

一个自制的比较low的刷题软件 一、背景 工作中往往涉及一些考试&#xff0c;比如阿里云ACP认证&#xff0c;华为GAUSS认证、软考等&#xff0c;应对这些考试的时候&#xff0c;我们往往是先看书后刷题&#xff08;当然也有直接刷题的大神&#xff0c;毕竟考试&#xff0c;懂的…...

【Java 集合】List接口 —— ArrayList 与 LinkedList 详解

List接口继承自Collection接口&#xff0c;是单列集合的一个重要分支。 在List集合中允许出现重复的元素&#xff0c;所有的元素是以一种线性方式进行存储的&#xff0c;在程序中可以通过索引&#xff08;类似于数组中的元素角标&#xff09;来访问集合中的指定元素。另外&…...

通信工程学习:什么是PNF物理网络功能

PNF:物理网络功能 PNF(Physical Network Function)即物理网络功能,是指支持网络功能的物理设备。以下是关于PNF的详细解释: 一、定义与特点 定义: PNF是网络设备厂商(如Cisco、华为、H3C等)通过专用硬件实体提供软件功能的设备。这些设备直接在物理服务器上运…...

Unity的Text组件中实现输入内容的渐变色效果

要在Unity的Text组件中实现输入内容的渐变色效果&#xff0c;默认的Text组件不直接支持渐变色。但是&#xff0c;你可以通过以下几种方式实现&#xff1a; ### 1. **使用Shader**来实现渐变效果 通过自定义Shader为Text组件创建一个渐变效果。这是一个常用的做法&#xff0…...

network-scripts目录下没有ens33文件的问题

作者&#xff1a;程序那点事儿 日期&#xff1a;2023/11/09 06:52 systemctl start NetworkManager #开启网络管理器nmcli con show #查看ens33网卡对应的是ifcfg-Wired_connection_3这个文件&#xff08;网络管理器要开启&#xff0c;不然报错&#xff09;&#xff0c;或者根据…...

OpenHarmony(鸿蒙南向)——平台驱动指南【DAC】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DAC&#xff08;Digital to Analog Converter&…...

10.Lab Nine —— file system-下

Symbolic links 添加符号链接 1.添加有关symlink系统调用的定义声明&#xff0c;包括kernel/syscall.h, kernel/syscall.c, user/usys.pl 和 user/user.h. 2.添加新的文件类型T_SYMLINK到kernel/stat.h中&#xff0c;添加新的文件标识位O_NOFOLLOW到kernel/fcntl.h中 3.在ken…...

低代码中实现数据映射的必要性与方案

在数字化转型的浪潮中&#xff0c;低代码平台因其快速开发和灵活性而受到越来越多企业的青睐。然而&#xff0c;随着业务需求的复杂化&#xff0c;单纯依赖低代码工具往往难以满足企业在数据处理和业务逻辑上的要求。数据映射作为连接不同数据源和业务逻辑的桥梁&#xff0c;显…...

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…...

四元组问题

目录 问题描述 输入格式 输出格式 样例输入 样例输出 说明 评测数据规模 运行限制 原题链接 代码思路 问题描述 从小学开始&#xff0c;小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期&#xff0c;他遇到了一个非常有趣的问题&…...

如何用Prometheus监控禁用了Actuator的SpringBoot?

需求来源 prometheus监控微服务一般都是使用micrometer结合actuator来做&#xff1a; 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency> <d…...

使用TensorFlow实现一个简单的神经网络:从入门到精通

使用TensorFlow实现一个简单的神经网络:从入门到精通 在现代数据科学和机器学习领域,神经网络是一个非常重要的工具。TensorFlow 是一个开源的深度学习框架,由 Google 开发和维护,它使得构建和训练神经网络变得更加容易。本文将详细介绍如何使用 TensorFlow 实现一个简单的…...

应用DFX能力介绍

一、HarmonyOS生态DFX能力范围 围绕开发者&#xff0c;构建三方应用和设备从开发到维护全生命周期所必需、有竞争力、有特色的调试调优、定位、维护能力。 二、HarmonyOS DFX能力全集 三、DFX设计主要范围 1、HiLog 日志分类 日志常用命令 日志级别 日志规则 2、HiAppEvent 完…...

第三篇 第20章工程计价数字化与智能化

第三篇 工程计价 第20章 工程计价数字化与智能化 20.1 BIM在工程计价中的应用 20.1.1 BIM概述 1.定义 在建设工程及设施全生命周期内,对其物理特征和功能特征信息进行数字化表达,依次设计、施工、运营的过程和结果的总称。应由核心层、共享层、专业领域层、资源层四个概念层…...

成语700词(46~65组)

目录 46.熟悉、了解、知晓相关(15 个)47.很常见不奇怪(6 个)48.看法一致与否(10 个)49.从细节看全貌(10 个)50.看事情透彻(11 个)51.对事情的态度与评价(7 个)52.数量多与少(11 个)53.建筑相关(6 个)54.相同与不同(17 个)55.技艺精湛(10 个)56.与观看欣赏相…...

linux如何配置静态IP

文章目录 使用ip命令&#xff08;临时配置&#xff09;Debian/Ubuntu系统&#xff08;使用netplan&#xff09;CentOS/RHEL系统&#xff08;使用nmcli或nmtui&#xff09;使用nmcli&#xff08;命令行界面&#xff09;使用nmtui&#xff08;文本用户界面&#xff09;通过图形界…...

Dependency Check:一款针对应用程序依赖组件的安全检测工具

关于Dependency Check Dependency-Check 是一款软件组合分析 &#xff08;SCA&#xff09; 工具&#xff0c;可尝试检测项目依赖项中包含的公开披露的漏洞。它通过确定给定依赖项是否存在通用平台枚举 &#xff08;CPE&#xff09; 标识符来实现此目的。如果找到&#xff0c;它…...

Python 从入门到实战28(文件的读操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了文件的打开、创建、关闭的相关知识。今天我们将…...

3PEAK思瑞浦 TPT1051V-SO1R SOP8 CAN收发器

特性 符合IS011898标准支持CAN FD和最高达5 Mbps的数据速率典型环路延迟:110纳秒5V电源供应&#xff0c;3.0V~5.5VI0接口接收器共模输入电压:士30V总线故障保护:42VCAN网络最多支持110个节点结温范围从-40C到150C闩锁性能超过500mA总线引脚ESD保护:-8kV人体模型 -1.5kV充电设备…...

SEO_新手必看的SEO优化入门教程与常见误区

什么是SEO优化&#xff1f; SEO优化&#xff0c;全称搜索引擎优化&#xff0c;是指通过优化网站内容和结构&#xff0c;使其在搜索引擎&#xff08;如百度、谷歌&#xff09;中获得更高排名的一系列活动。SEO的目的是提高网站的自然流量&#xff0c;从而增加潜在客户和销售机会…...

AI写论文超厉害!4款AI论文生成工具,解决毕业论文写作难题!

还在为撰写期刊论文而烦恼吗&#xff1f;面对成堆的文献、复杂的格式要求以及无休止的修改&#xff0c;许多学术人员常常感到效率低下。这并不奇怪&#xff01;不过&#xff0c;不必太担心&#xff0c;以下将推荐4款实测有效的AI论文写作工具&#xff0c;它们能帮助你在论文文献…...

从零开始用Typora写技术文档:完整配置指南与高效排版秘籍

从零开始用Typora打造专业技术文档&#xff1a;配置、排版与效率全攻略 在技术写作领域&#xff0c;文档的呈现质量往往直接影响知识传递的效果。Typora作为一款轻量级Markdown编辑器&#xff0c;凭借其即时渲染、简洁界面和强大的扩展功能&#xff0c;已成为众多开发者和技术作…...

别再混淆了!一文搞懂目标检测中的AP、mAP和mAP@0.5:0.95区别

目标检测评估指标全解析&#xff1a;从AP到mAP0.5:0.95的实战指南 在计算机视觉领域&#xff0c;目标检测模型的性能评估一直是研究者关注的焦点。面对AP、mAP、mAP0.5:0.95等专业术语&#xff0c;不少开发者容易混淆它们的计算方式和适用场景。本文将深入剖析这些关键指标的技…...

Ubuntu20.04下ROS2与MoveIt2环境配置全攻略:从虚拟环境到避坑指南

Ubuntu 20.04下ROS2与MoveIt2环境配置实战指南 机器人操作系统&#xff08;ROS&#xff09;作为现代机器人开发的基石&#xff0c;其第二代的ROS2凭借更强大的实时性和分布式架构&#xff0c;正在成为工业界和学术界的新宠。而MoveIt2作为ROS2中的运动规划框架&#xff0c;为机…...

Kafka消费者在大数据生态中的集成:从数据湖到AI管道的完整架构

一、引言在数字化转型的浪潮中&#xff0c;企业对数据处理的需求已从传统的批处理模式转向实时化、高并发的场景。无论是金融风控中的毫秒级欺诈检测、电商交易中的个性化实时推荐&#xff0c;还是物联网监控中的异常预警&#xff0c;实时数据流处理能力已成为业务竞争力的核心…...

Java记录模式安全边界警告:3类不可序列化场景、2种反编译泄露风险(Oracle安全白皮书节选)

第一章&#xff1a;Java记录模式安全边界警告&#xff1a;3类不可序列化场景、2种反编译泄露风险&#xff08;Oracle安全白皮书节选&#xff09;不可序列化的三类典型场景 Java记录&#xff08;Record&#xff09;类型在设计上强调不可变性与透明性&#xff0c;但其默认序列化行…...

Redis持久化:从AOF到RDB,如何实现数据不丢失?

Redis属于内存数据库&#xff0c;但为了防止宕机等导致的数据丢失&#xff0c;也有对应的数据持久化技术。持久化主要作用就是数据备份&#xff0c;即将数据存储在硬盘&#xff0c;保证数据不会因进程退出而丢失。 AOF持久化 Append Only File 类似于Mysql的binlog日志类似&…...

告别数据下载烦恼:5分钟用GEE(Google Earth Engine)在线获取任意区域DEM高程数据

告别数据下载烦恼&#xff1a;5分钟用GEE在线获取任意区域DEM高程数据 在科研和工程实践中&#xff0c;数字高程模型&#xff08;DEM&#xff09;是地形分析的基础数据。传统获取方式往往需要经历数据搜索、分幅下载、格式转换、多图拼接等一系列繁琐步骤&#xff0c;对于非GI…...