多机部署,负载均衡-LoadBalance

news2024/10/1 5:39:18

文章目录

  • 多机部署,负载均衡-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);
    @Autowired
    private OrderMapper orderMapper;

    @Resource
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;



    private static AtomicInteger atomicInteger = new AtomicInteger(1);
    private static List<ServiceInstance> instances;
    @PostConstruct
    public 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
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
修改IP,端口号为服务名称
@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private 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 {
    @Bean
    ReactorLoadBalancer<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
    @Bean
    public 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();
    }
}

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

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

相关文章

面试系列-携程暑期实习一面

Java 基础 1、Java 中有哪些常见的数据结构&#xff1f; 图片来源于&#xff1a;JavaGuide Java集合框架图 Java 中常见的数据结构包含了 List、Set、Map、Queue&#xff0c;在回答的时候&#xff0c;只要把经常使用的数据结构给说出来即可&#xff0c;不需要全部记住 如下&…

Stable Diffusion绘画 | 插件-Addition Networks:单独控制LoRA

当 SD 使用到了进阶阶段&#xff0c;经常需要添加多个 LoRA 来生成图片&#xff0c;因此&#xff0c;提示词中难免会出现一系列的 LoRA 和相关触发词。 但很多时候&#xff0c;我们直接复制网上别人分享的完整提示词&#xff0c;会发现生成出来的效果不一样&#xff0c;这是怎么…

【嵌入式】嵌入式系统和图形用户界面(GUI)开发的图形库和框架

目录 1. **LVGL (Light and Versatile Graphics Library)**2. **TouchGFX**3. **EmWin**4. **Qt for Embedded**5. **SDL (Simple DirectMedia Layer)**6. **Nano-X**7. **Cairo**8. **GTK**9. **Allegro**10. **Qt Quick (QML)**11. **GUIX**12. **FLTK (Fast, Light Toolkit)…

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法&#xff1a;error、require 和 assert 在 Solidity 开发中&#xff0c;异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常&#xff1a;error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…

心觉:如何重塑高效学习的潜意识(2)明白你为什么这么学,才能学得更好

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作181/1000天 上一篇文章我们讲了系统化学习和边学边用两种方法的优缺点 为什么有些人喜欢这种而不是那种 他们的底层心理逻辑不一…

智能识别猫猫

鸡蛋饼是什么猫 今天&#xff0c;有一位爱猫人士找到了我&#xff1a;“9月25日啦&#xff0c;炉石传说重新开服了&#xff01;” 我&#xff1a;“哦&#xff01;我知道这个&#xff0c;你是说&#xff0c;我现在该去领金卡了吗&#xff1f;” 爱猫人士&#xff1a;“不&am…

VMware下Ubuntu找不到共享文件夹

在VMware的设置中已经设置了共享文件夹&#xff0c;在Ubuntu系统中找不到&#xff0c;参考了网上其他的文章&#xff0c;发现还是不能解决问题&#xff0c;无意中尝试了一小步&#xff0c;没想到成功解决了&#xff0c;在这里记录一下。 1&#xff09;首先查询本机的gid 2&…

聚焦Llama新场景和AR眼镜,扎克伯格用AI赋能元宇宙,Meta Connect 2024开发者大会直播约起...

作者&#xff1a;十九 编辑&#xff1a;十九&#xff0c;李宝珠 北京时间 9 月 26 日凌晨 1 点&#xff0c;Meta Connect 2024 开发者大会即将举行&#xff0c;马克扎克伯格将聚焦 AI 和元宇宙&#xff0c;向大家分享 Llama 模型的更多潜在应用&#xff0c;并介绍 Meta 最新产品…

2024年汉字小达人区级自由报名备考冲刺:最新问题和官模题练一练

今天是2024年第十一届汉字小达人的区级自由报名活动的第二天。 我们继续回答几个关于汉字小达人的最新问题&#xff0c;做几道2024年官方模拟题&#xff0c;帮助孩子们少走弯路&#xff0c;再冲刺一般&#xff0c;更精准地备考2024年汉字小达人。 【温馨提示】本专题在比赛期…

芯科科技2024年Works With开发者大会登陆上海,物联网和人工智能的变革性融合带来无限精彩

谷歌、三星等生态大厂将带来重磅演讲和圆桌讨论&#xff0c;亦可切身体验多样化无线技术实作 中国&#xff0c;北京 – 2024年9月25日 – 安全、智能无线连接技术领域的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;&a…

MySQL InnoDB MVCC读写逻辑分析与调测

目标 1、构建MVCC读写场景 2、gdb调试MVCC过程&#xff0c;输出流程图&#xff08;函数级别调用过程&#xff09; 前提 准备1 打开服务端 查询mysqld进程号 线程树 打开客户端&#xff0c;想创建几个事务号就打开几个客户端 准备2 数据库mvcc&#xff0c;两个表test和stu…

JVM(HotSpot):虚拟机栈(JVM Stacks)之线程问题排查方法

文章目录 前言一、CPU占用过大二、程序运行很长时间没有结果三、总结 前言 本篇讲的排查都是基于Linux环境的。 一、CPU占用过大 这个一般是出现了死循环导致的。 1、先用top命令查看占用CPU的进程ID top2、再用ps命令查看对应的线程 就看一查看到对应的线程id ps H -eo …

王道考研视频——操作系统笔记

操作系统第一章&#xff01;入门 王道考研视频——操作系统笔记&#xff0c;第一部分&#xff0c;操作系统的概念和体系结构 0.0 课程白嫖指南_哔哩哔哩_bilibili0.0 课程白嫖指南是王道计算机考研 操作系统的第1集视频&#xff0c;该合集共计84集&#xff0c;视频收藏或关注UP…

openkylin介绍及其特点和优势

openKylin&#xff08;开放麒麟&#xff09;openKylin&#xff08;开放麒麟&#xff09; 社区是在开源、自愿、平等和协作的基础上&#xff0c;由基础软硬件企业、非营利性组织、社团组织、高等院校、科研机构和个人开发者共同创立的一个开源社区&#xff0c;致力于通过开源、开…

51单片机应用开发---keil 创建一个新工程并用Protues 8仿真(以点亮LED为例)

实现目标 1、掌握keil V5软件 创建一个新工程&#xff1b; 2、具体目标&#xff1a;1.会新建一个工程&#xff1b;2.编程实现点亮开发板的LED1. 一、新建工程步骤 1.1 在桌面上新建一个名字为 LED的文件夹 1.2 双击打开Keil uVision5 软件&#xff0c;点击 Project —>…

HTML和CSS中的浮动以及边框塌陷解决方案(内置练习及答案)

一、浮动概述 在HTML和CSS中&#xff0c;“浮动”&#xff08;Float&#xff09;是一种布局技术&#xff0c;它允许元素脱离其正常的文档流&#xff0c;向左或向右移动&#xff0c;直到它的外边缘碰到包含框或另一个浮动元素的边缘。浮动元素仍然保持块级盒模型的特性&#xff…

【GUI设计】基于图像分割的GUI系统(6),matlab实现

博主简介&#xff1a; 如需获取设计的完整源代码或者有matlab图像代码项目需求/合作&#xff0c;可联系主页个人简介提供的联系方式或者文末的二维码。博客内容有疑问可联系沟通&#xff08;博主邮箱&#xff1a;3249726188qq.com&#xff09;。 ~~~~~~~~~~~~~~~~~~~~~~~…

【ComfyUI】减少连线的节点——cg-use-everywhere

源码&#xff1a;https://github.com/chrisgoringe/cg-use-everywhere 介绍&#xff1a;一组节点&#xff0c;允许数据“广播”到一些或所有未连接的输入端。大大减少了链接混乱。 【秋葉aaaki】comfyui一键运行包 夸克网盘&#xff1a;https://pan.quark.cn/s/64b808baa960 …

PMP--二模--解题--131-140

文章目录 反例14.敏捷–角色–教练/项目经理–仆人式领导–职责–核心工作–消除障碍&#xff1b;–作用–促进合作&#xff08;关键字&#xff1a;合作&#xff0c;一起解决问题&#xff09;--不是出现“合作”就一定选131、 [单选] 一个项目经理被分配到一个针对客户的分析项…

【网络安全】网络基础第一阶段——第三节:网络协议基础---- VLAN、Trunk与三层交换技术

目录 一、交换机 1.1 交换机定义 1.1.1 交换机 1.2 工作原理 1.2.1 数据帧的转发 1.2.2 交换机处理数据帧的三种行为 1.2.3 交换机通信 二、虚拟局域网&#xff08;VLAN&#xff09; 2.1 虚拟局域网简介 2.1.1 为什么需要VLAN 2.1.2 广播域的分割与VLAN的必要性 2.…