05-LoadBalancer负载均衡

news/2024/12/22 16:20:25/文章来源:https://www.cnblogs.com/changming06/p/18444219

1.Ribbon目前也进入维护模式

1.1 Ribbon介绍

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

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

https://github.com/Netflix/ribbon

1.2 Ribbon替代方案


spring-cloud-loadbalancer

2.spring-cloud-loadbalancer概述

2.1 官网

2.2 是什么

LB负载均衡(Load Balance)是什么

简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用),常见的负载均衡有软件NginxLVS,硬件F5

spring-cloud-starter-loadbalancer组件是什么

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

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html

2.3 面试题

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

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。

loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

个人理解,客户端负载均衡,是由客户端,选择向那台机器发起请求,并获得响应。而服务端负载均衡,是由服务器端(nginx),决定某个请求,由那台机器处理,然后响应给客户端。

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

3.1 理论


LoadBalancer 在工作时分成两步:

第一步,先选择ConsulServer从服务端查询并拉取服务列表,知道了它有多个服务(上图3个服务),这3个实现是完全一样的,

默认轮询调用谁都可以正常执行。类似生活中求医挂号,某个科室今日出诊的全部医生,客户端你自己选一个。

第二步,按照指定的负载均衡策略从server取到的服务注册列表中由客户端自己选择一个地址,所以LoadBalancer是一个客户端的负载均衡器。

3.2 实操

3.2.1 官网参考如何正确使用

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html


3.2.2 按照8001拷贝新建8002

3.2.3 启动Consul,然后启动8001和8002

启动Consul

consul agent -dev

获取在consul中配置的测试信息,通过8001或8002接口

bug

在consul中的配置重启后,消失了

3.2.4 Consul数据持久化配置并注册为Window服务

1.在consul.exe的同级目录下,新建mydata文件夹

2.新建consul_start.bat文件

@echo.Consul Start......  
@echo off  
@sc create Consul binpath= "D:\Develop\consul\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect  1  -data-dir D:\Develop\consul\mydata   "
@net start Consul
@sc config Consul start= AUTO  
@echo.Consul start is OK......success
@pause

3.管理员权限打开

4.启动结果

5.win后台

会多出consul服务

6.后续consul的配置数据会保存到mydata文件夹

3.2.5 修改Order模块

1.引入依赖

<!--loadbalancer-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

2.新增接口

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

3.consul服务


4.测试

http://localhost:8080/consumer/pay/get/info

访问改接口,可见交替访问8001和8002

3.3 小总结

3.3.1 使用DiscoveryClient动态获取上线的服务列表

3.3.2 订单模块新增代码
@Resource
private DiscoveryClient discoveryClient;@GetMapping("/discovery")
public String discovery() {//获取所有的consul中的服务名List<String> services = discoveryClient.getServices();for (String element : services) {System.out.println(element);}System.out.println("===================================");//获取key服务的所有服务实例List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");for (ServiceInstance element : instances) {//服务实例名 + 服务主机名 + 服务端口号 + 服务urlSystem.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t" + element.getUri());}return instances.get(0).getServiceId() + ":" + instances.get(0).getPort();
}

输出信息

cloud-consumer-order
cloud-payment-service
consul
===================================
cloud-payment-service	x	8001	http://x:8001 x是主机名
cloud-payment-service	x	8002 	http://x:8002

3.3.3 负载均衡原理小总结

负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从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

8001+ 8002 组合成为集群,它们共计2台机器,集群总数为2, 按照轮询算法原理:

当总请求数为1时: 1 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001

当总请求数位2时: 2 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002

当总请求数位3时: 3 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001

当总请求数位4时: 4 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002

如此类推......

4.负载均衡算法原理

4.1 默认算法,有几种

4.1.1 官网

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html#switching-between-the-load-balancing-algorithms

4.1.2 默认两种


轮询

public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer

随机

public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer 

源码

略,见org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer接口

4.2 算法切换

@LoadBalancerClient(value = "cloud-payment-service",configuration = RestTemplateConfig.class)
public class RestTemplateConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}}

The classes you pass as @LoadBalancerClient or @LoadBalancerClients configuration arguments should either not be annotated with @Configuration or be outside component scan scope.

在RestTemplateConfig的类上,有@LoadBalancerClient或者@LoadBalancerClients,就不该在使用@Configuration注解了,包含了。

Configuration(proxyBeanMethods = false)
@Import(LoadBalancerClientConfigurationRegistrar.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoadBalancerClient 
@Configuration(proxyBeanMethods = false)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Documented
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients

只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PbootCMS错误提示:执行SQL发生错误!错误:no such column: def1

问题描述 在PbootCMS v3.0.5及以下版本升级到v3.0.6后,后台栏目管理操作中出现提示:“执行SQL发生错误!错误:no such column: def1”。原因是升级过程中 SQL 语句未执行成功,导致程序报错。 解决方案手动执行SQL脚本下面是适用于SQLite数据库的升级脚本,用于添加缺失的字…

pbootcms编辑器过滤div代码解决办法

在使用PbootCMS建站时,如果需要在专题内容中加入含有HTML代码的文字,但发现编辑器将 div 标签转换成了 p 标签,可以通过以下步骤进行修改。 修改步骤修改 ueditor.all.js 文件找到 core->extend->ueditor->ueditor.all.js 文件。 在大约第 10830 行,将 allowDivTr…

PbootCMS如何重置程序后台的文章id,从1开始

在 PBootCMS 中,如果你需要重置程序后台的文章 ID 使其从 1 开始,可以使用 SQL 语句来实现这一目标。以下是一个详细的步骤说明和示例 SQL 语句。 步骤说明备份数据库:在执行任何操作前,务必先备份数据库,以防数据丢失。清空文章表:使用 TRUNCATE 语句清空文章表。重置自…

PbootCMS建站系统怎么修改域名授权提示信息

在 PBootCMS 中,如果你上传网站到服务器后使用域名访问,但没有获取到官方的域名授权码,系统会提示未授权的相关信息。为了避免客户看到这些提示信息,官方提供了一个简单的解决方案,即在网站根目录下创建一个 sn.html 文件,并编写自定义的提示信息。 解决方案创建 sn.html…

pbootcms修改后台文章显示最大数量

如果你想修改 PBootCMS 后台文章列表每页显示的数量,可以通过修改后台相关代码来实现。以下是具体的步骤和示例代码。 步骤打开相关文件:打开文件 \APPs\admin\view\default\content\content.html。修改每页显示数量:在文件中搜索 “每页显示数量”,找到对应的代码片段,并…

解决 PBootCMS 网站迁移后出现的 “No input file specified” 错误

1. 检查 .user.ini 文件进入网站根目录:使用 FTP 客户端或 SSH 连接到服务器,进入网站根目录。查找 .user.ini 文件:使用命令 ls -la 查看隐藏文件。shls -la删除 .user.ini 文件:如果存在 .user.ini 文件,删除它。shrm .user.ini2. 重启服务器重启 Apache 服务:使用以下…

找到并修复 SQL 脚本中的重复字段问题。确保每个字段定义唯一,避免出现 duplicate column name 的错误

假设你的 SQL 脚本如下:-- 创建表 CREATE TABLE articles (id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(255) NOT NULL,content TEXT,picstitle VARCHAR(255),picstitle VARCHAR(255) -- 这里重复了 picstitle 字段 );-- 插入数据 INSERT INTO articles (id, title, co…

准确地判断用户是否登录,并避免由于 Cookie 过期但仍显示已登录的问题

在 PBootCMS 中,判断用户是否登录通常使用 {pbOOT:ISLOGIN} 标签。然而,如果发现该标签不够准确,尤其是在本地 Cookie 已经过期但仍然显示已登录的情况,可以通过更精确的方式来判断用户登录状态。 解决方案检查 Session 和 Cookie:确认用户的 Session 和 Cookie 是否有效。…

PBOOTCMS判断登录是否登录代码

修改控制器文件:在 IndexController.php 文件中添加 isUserLoggedIn() 方法,用于判断用户是否登录。修改模板文件:在模板文件中引入控制器类,并实例化控制器对象。 使用 isUserLoggedIn() 方法来判断用户是否登录,并输出相应的信息。优点更准确的判断:通过检查 Session 和…

pbootcms自动清理runtime缓存文件释放你的空间压力

在使用 PBootCMS 配合阿里云虚拟主机时,确实可能会遇到运行时缓存文件过多的问题。以下是一种解决方案,通过自动清理缓存文件来解决这一问题。 步骤一:修改 ExtLabelController.php 文件打开文件:打开 apps/home/controller/ExtLabelController.php 文件。添加清理脚本:在…

中缀表达式和后缀表达式

算术表达式中缀表达式转后缀表达式栈的深度 栈的深度就是指栈中元素的个数 后缀表达式求值

pbootcms列表页调用tag标签

在 PBootCMS 中,可以使用 {pboot:tags} 标签来调用文章的标签。这里分别介绍了列表页和内容页中如何调用标签。 列表页中调用标签 在列表页中,可以使用 {pboot:tags} 标签嵌套在 {pboot:list} 标签中来调用每个文章的标签。 示例代码<!DOCTYPE html> <html lang=&qu…