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

[SpringCloud][7]负载均衡介绍,以及一些搭建

[SpringCloud][7]负载均衡介绍,以及一些搭建

文章目录

  • 负载均衡介绍
    • 简单实现
      • 问题描述
      • 问题解决
    • 什么是负载均衡
    • 负载均衡的一些实现
      • 服务端负载均衡
      • 客户端负载均衡

负载均衡介绍

简单实现

问题描述

观察上篇文章的远程调用代码

List<
ServiceInstance> instances = discoveryClient.getInstances("product-service");
// 服务可能有多个,获取第一个 
EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);
  1. 根据应用名称获取了服务实例列表
  2. 从列表中选择了一个服务实例

思考:如果一个服务对应多个实例呢?流量是否可以合理的分配到多个实例?
现象观察

  • 我们再启动 2 个 product-service 实例
  • 选中要启动的服务,右键选择 Copy Configuration...|320

在弹出的框中,选择 Modify options -> Add VM optionsimage.png|454
添加 VM options-Dserver.port=9091

  • 9091 为服务启动的端口号,根据自己的情况可修改
    image.png|390

现在 IDEAService 窗口就会多出一个启动配置,右键启动服务就可以了image.png

同样的操作,再启动一个实例,共启动三个服务器image.png|310

观察 Eureka,可以看到 product-service 下有三个实例:image.png|424


访问结果
访问: http://127.0.0.1:8080/order/1
image.png

  • 通过日志可以发现,请求多次访问,都是同一台机器

问题解决

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

我们可以针对上述代码简单修改:

package org.example.order.service;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.order.mapper.OrderMapper;
import org.example.order.model.OrderInfo;
import org.example.order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.eureka.EurekaServiceInstance;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Service
public class OrderService
{
@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 selectOrderById(Integer orderId) {
OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
//String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId(); 
// 服务可能有多个,轮询获取实例 
int index = atomicInteger.getAndIncrement() % instances.size();
ServiceInstance instance = instances.get(index);
log.info(instance.getInstanceId());
// 拼接 URL 
String url = instance.getUri() + "/product/" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class)
;
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
  • @PostConstruct :在 Spring 容器完成 依赖注入(DI) 后,自动调用标注了 @PostConstruct 的方法,用于执行初始化逻辑。

    • 就是当这个 Bean 创建完成并注入完需要的依赖后,Spring 会自动调用我标注的方法一次,用来做一些初始化的操作。
  • discoveryClient.getInstances() 可以返回当前所有可用的 product-service 实例。

    • instances 列表包含了所有可用的 product-service 实例,每个实例包含了服务的 URI 和其他元数据
  • int index = atomicInteger.getAndIncrement() % instances.size():该逻辑基于递增的计数器来决定访问哪个实例。每次访问时,计数器会递增,并且通过 index % instances.size() 确保能够在实例列表中轮询(即循环访问所有实例)。

    • 例如,如果有 3 个实例,当 atomicInteger 的值为 1、2、3、4 时,它会依次访问

观察日志:image.png|387

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

通过使用 DiscoveryClient 获取 product-service 的所有实例,并结合 AtomicInteger 实现轮询负载均衡,将请求均匀地分发到 product-service 的各个实例上,从而有效地进行负载均衡。

什么是负载均衡

负载均衡(Load Balance,简称 LB),是高并发,高可用系统必不可少的关键组件

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

  • 一个团队最开始只有一个人,后来随着工作量的增加,公司又招聘了几个人,负载均衡就是:如何把工作量均衡的分配到这几个人身上,以提高整个团队的效率

负载均衡的一些实现

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

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

服务端负载均衡

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


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

客户端负载均衡

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


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

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

RibbonSpring Cloud 早期的默认实现,由于不维护了,所以最新版本的 Spring Cloud 负载均衡集成的是 Spring CloudBalancerSpring Cloud 官方维护)image.png|460

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

http://www.rkmt.cn/news/18105.html

相关文章:

  • AI元人文:创新空间的深度探索与未来蓝图
  • Redis 64字节分界线与跳表实现原理 - 实践
  • 深入解析:微服务通信:5大消息队列横向对比
  • 深入解析:抖音私信助手私域用户触达私信群聊小工具小程序开源
  • 2025 年最新推荐!依托优质运输网络的国际搬家海运公司排行榜:覆盖澳洲多地家具海运需求澳洲/悉尼/墨尔本/大型家具海运公司推荐
  • 2025舒适轮胎最新推荐榜:卓越减震与静音性能的驾乘体验之选
  • 螺杆泵厂家最新推荐榜:高效耐用与技术创新实力解析
  • CF做题记录
  • 2025 年中国搬家服务公司最新推荐榜:聚焦海运移民家具运输等需求,精选优质企业实测解析国际/国际海运/国际移民/家具海运/回国搬家海运公司推荐
  • 完整教程:电商日志分析项目:Hadoop + Hive + Spark SQL
  • 03_并发锁实现
  • 爱人先爱己
  • 最简单的 Web 打印方案:用 5 分钟上手 web-print-pdf(npm 包) - 实践
  • 如何将GIS属性一键快速标注到AutoCAD图纸上?
  • zedboard + AD-FMCOMMS3-EBZ HDL VIVADO 工程构建(二) 构建HDL项目
  • 2025年超微粉碎机优质实力厂家推荐,产品涵盖低温无尘粉碎机/液氮冷冻/万能/锤式粉碎机!
  • 2025 年高低温试验箱制造厂家最新推荐排行榜:精选优质品牌,助力企业精准选购可靠测试设备恒温恒湿试验箱/高低温试验箱厂家推荐
  • 一堆todo - 吾辈当奋斗
  • Rudin 数学分析第二章
  • aardio在其他窗体调用主窗体的函数
  • openssl 生成证书
  • 基于自适应观测器的无传感器感应电动机矢量控制仿真
  • 深入解析:分布式之RabbitMQ的使用(2)
  • 【IEEE出版、EI检索稳定】 第五届数字化社会与智能系统国际学术会议(DSInS 2025)
  • 【2025-10-03】连岳摘抄
  • maxscript的自动科学计数法转换导致dotnet json序列化识别错误
  • 国产项目管理工具Gitee:本土化优势赋能企业数字化转型
  • 2025 年国内一体板厂家最新推荐排行榜:装配式 / 珍珠岩 / 免拆 / 外墙保温品类优质企业权威精选
  • odoo18安装环境
  • Group Theory Note 2/2 (Michael Artin Algebra Chapter 2 Groups) (to complete)