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

【负载均衡】LoadBalance场景演示

服务端⾼并发分布式结构演进之路-CSDN博客文章浏览阅读976次,点赞11次,收藏9次。在进行技术学习过程中,由于大部分读者没有经历过一些中大型系统的实际经验,导致无法从服务端⾼并发分布式结构演进之路-----在进行技术学习过程中,由于大部分读者没有经历过一些中大型系统的实际经验,导致无法从全局理解一些概念,所以本文以一个"电子商务"应用为例,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,方便大家对后续知识做深入学习时有一定的整体视野。https://blog.csdn.net/qq_45875349/article/details/139639760?spm=1001.2014.3001.5501对于负载均衡的概念还不了解的可以我的上面这篇博客的 2.3 小节去了解一下。

负载均衡(Load Balancing)是一种将网络流量或计算任务分配到多个服务器或资源上的技术,目的是优化资源使用、最大化吞吐量、减少响应时间、提高系统的可靠性和可用性。通过平衡工作负载,负载均衡可以避免单个服务器或资源过载,从而提高整个系统的性能和稳定性。

1问题描述

我们的订单服务每次被调用的时候,都会通过Eureka的服务发现去获取到商品服务的实例列表。如果仅仅单纯获取某一个商品服务,那么流量就一直压在一台服务器之上。如果⼀个服务对应多个实例呢? 流量是否可以合理的分配到多个实例呢?

2场景复现

为了更好的演示效果,我们可以多启动几个product-service的实例。【不修改代码,修改修改配置,调整端口号并启动服务】  项目名名称和端口号可以自己设定,两者最好有对应关系,方便观察。

apply之后,现在IDEA的Service窗⼝就会多出来⼀个启动配置, 右键启动服务就可以,同样的操作, 再启动1个实例, 共启动3个服务。启动后观察Eureka,可以看到product-service下有三个实例:

现在我们来访问订单服务,然后订单服务远程调用商品服务。

结果发现,都是请求多次访问, 都是同⼀台机器.

这肯定不是我们想要的结果, 我们启动多个实例, 是希望可以分担其他机器的负荷, 那么如何实现呢?

3 解决方案

先来看看现在的带代码,为什么会出现这样的现象,也就是我们再去获取服务的时候,使用的方式是不对的,这样每次获取到的服务大概率是相同的。

 

好的,那么我就来来写代码。修改远程调用的逻辑

package com.guan.order.service;import com.guan.order.mapper.OrderMapper;
import com.guan.order.model.OrderInfo;
import com.guan.product.model.ProductInfo;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;@Service
@Slf4j
public class OrderService {@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 selectOrderByID(Integer orderID) {OrderInfo orderInfo = orderMapper.selectOrderById(orderID);// 从Eureka获取服务列表List<ServiceInstance> instances = discoveryClient.getInstances("product-service");//有多个服务,根据轮询获取int index = atomicInteger.getAndIncrement() % instances.size();String uri = instances.get(index).getUri().toString();String url = uri + "/product/" + orderInfo.getProductId();log.info("远程调用url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

现在在来观察服务。

通过⽇志可以看到, 请求被均衡的分配在了不同的实例上, 这就是负载均衡

4 什么是负载均衡

负载均衡(Load Balance,简称 LB) , 是⾼并发, ⾼可⽤系统必不可少的关键组件.
当服务流量增⼤时, 通常会采⽤增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载
⼀个团队最开始只有⼀个⼈, 后来随着⼯作量的增加, 公司⼜招聘了⼏个⼈. 负载均衡就是: 如何把⼯作量均衡的分配到这⼏个⼈⾝上, 以提⾼整个团队的效率

5 负载均衡的一些实现

上面的例子中,我们只是简单的对实例进行了轮询,但真实的业务场景会更加复杂,比如根据机器的配置进行负载分配,配置高的分配的流量高,配置低的分配流量低等.也就是“能者多劳”。

服务多机部署时,开发人员都需要考虑负载均衡的实现,所以也出现了一些负载均衡器,来帮助我们实现负载均衡.

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

服务端负载均衡

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

客户端负载均衡

在客户端进行负载均衡的算法分配.
把负载均衡的功能以库的方式集成到客户端,而不再是由一台指定的负载均衡设备集中提供,比如Spring Cloud的Ribbon,请求发送到客户端,客户端从注册中心(比如Eureka)获取服务列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问.Ribbon是Spring Cloud早期的默认实现,由于不维护了,所以最新版本的Spring Cloud负载均衡集成的是Spring Cloud LoadBalancer(Spring Cloud官方维护)

客⼾端负载均衡和服务端负载均衡最⼤的区别在于服务清单所存储的位置

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JsonCpp库的使用
  • macOS 安装 Homebrew
  • 记录使用 xlsx 前端导出文件
  • App推广新篇章:Xinstall带你走出数据迷雾,实现高效推广!
  • ZTP(Zero Touch Provisioning)
  • 情侣点餐小程序(零基础小白)(零成本运营)
  • Python计算机视觉编程——第四章 照相机模型与增强现实
  • 用户变渠道,Xinstall引领手游推广新潮流
  • 【网络安全】服务基础第一阶段——第五节:Windows系统管理基础---- DHCP部署与安全
  • 相机常见名词详解
  • 设计模式 18 备忘录模式
  • win11,vscode上用docker环境跑项目
  • graalvm jenkins maven 配置
  • 探索Ansible自动化运维:提高效率的关键工具
  • 【C++】手动实现String类的封装(分文件编译)
  • @jsonView过滤属性
  • 2017-09-12 前端日报
  • CentOS 7 修改主机名
  • iOS 颜色设置看我就够了
  • Java,console输出实时的转向GUI textbox
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Js基础知识(四) - js运行原理与机制
  • Spring声明式事务管理之一:五大属性分析
  • SQLServer之创建显式事务
  • Terraform入门 - 3. 变更基础设施
  • - 概述 - 《设计模式(极简c++版)》
  • 简单易用的leetcode开发测试工具(npm)
  • 蓝海存储开关机注意事项总结
  • 前端面试题总结
  • 前端设计模式
  • 前言-如何学习区块链
  • 通过几道题目学习二叉搜索树
  • 为视图添加丝滑的水波纹
  • 用jQuery怎么做到前后端分离
  • MyCAT水平分库
  • 第二十章:异步和文件I/O.(二十三)
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #数据结构 笔记一
  • (06)金属布线——为半导体注入生命的连接
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (C)一些题4
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (windows2012共享文件夹和防火墙设置
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (二)JAVA使用POI操作excel
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)springboot2.7.6集成activit5.23.0之集成引擎