多机部署,负载均衡

目录

负载均衡介绍

问题引出

什么是负载均衡

负载均衡的一些实现

服务端负载均衡

客户端负载均衡

[Spring Cloud LoadBalancer](#Spring Cloud LoadBalancer)

使用

负载均衡策略

自定义负载均衡策略

[LoadBalancer 原理](#LoadBalancer 原理)

服务部署

服务构建打包

完!


负载均衡介绍

问题引出

上篇文章中,实现远程调用的代码如下:

根据应用名称获取到了服务实例列表,从列表中选择了一个服务实例。

但如果一个服务对应多个实例呢?流量在这些实例中是如何分配?

现象观察:

在 Services 中先启动三个服务

然后再多启动两个 product-service 实例

此时观察 eureka,可用看到 product-service 下有三个实例。

此时访问:127.0.0.1:8080/order/1

通过日志发现,发出了多次访问,但都到了同一台机器上。

我们希望的是,启动多个实例之后,请求可用被分担到其他机器上。

解决:

对 order-service 中的 service 再进行修改:

重启 order-service,通过日志可以观察,请求被均衡的分配在了不同的实例上,这就是负载均衡

什么是负载均衡

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

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

负载均衡的一些实现

上面的案例中,我们简单对实例进行了轮询。在真实的开发环境中,会更加复杂。比如根据机器的配置进行负载分配...

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

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

服务端负载均衡

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

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

客户端负载均衡

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

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

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

Ribbon 是早期 Spring Cloud 的默认实现,由于不维护了,所以最新版本的 Spring Cloud 负载均衡集成的是 Spring Cloud LoadBalancer


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

Spring Cloud LoadBalancer

使用

  1. 给 RestTemplate 这个 Bean 添加 @LoadBalanced 注解
  1. 修改 IP 端口号为服务名称

这时候观察日志,就会发现请求已经被分配到 3 个实例上了。

负载均衡策略

负载均衡是一种思想。Spring Cloud Load Balancer 仅支持两种负载均衡策略:轮询策略和随机策略。

  1. 轮询:就是指服务器轮流处理用户的请求,这是一种实现最简单,也是最常用的策略。

  2. 随机:随机选择一个后端服务器来处理新的请求。

自定义负载均衡策略

Spring Cloud LoadBalancer 默认负载均衡策略是轮询策略,实现是 RoundBobinLoadBalancer。

如果要实现随机的负载均衡策略:

根据官网地址:Spring Cloud LoadBalancer :: Spring Cloud Commons

在我们的项目中,实现一个 CustomLoadBalancerConfiguration 类。

我们使用的 RestTemplate 实现的远程调用,则在上面加上 @LoadBalancerClient 注解

看一下 @LoadBalancerClient 注解的属性:name / value 和 configuration

在 RestTemplate 配置

重新部署,实现了随机负载分配~

LoadBalancer 原理

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

源码实现:

在 intercept 方法中,拦截了用户的 HttpRequest

  1. request.getURI() 从请求中获取了 URI

  2. orginalUri.getHost() 从 uri 中获取到了路径的主机名,也就是服务 id,product-service

  3. loadBalancer.execute 根据服务 id 进行负载均衡,并请求处理。

点进行进行追踪:

在 choose 方法中,根据 serviceId 和负载均衡策略,选择处理的服务。

在 choose 中,先获取负载均衡器,然后根据算法,选择一个服务实例

可以再点进去这个 choose 中进行观察

这个接口,就由轮询和随机负载均衡的实现~

服务部署

接下来我们将服务部署到 Linux 系统上

在 Linux 系统中,同样建立数据库。

服务构建打包

采用 Maven 进行打包,需要对三个服务分别进行打包

在子项目中 order-service 和 product-service 中的 pom 文件中进行如下配置

再对 application.yml 进行复制配置:

在 prod 生产环境中,对数据库的密码进行修改。

然后在 application.yml 文件中,让 Maven 仓库进行自动选择:

之后在 Maven 仓库中,选择 prod 环境进行打包

将 jar 包放到云服务器中,直接拖动文件到 xshell 窗口即可。

(第一次上传,需要安装 lrzsz : apt install lrzsz)

启动服务:

在云服务器控制台中,在防火墙设置中,将对应的端口号进行开放。

测试:

访问公网 ip:8080/order/1

远程调用实现成功。

完!

相关推荐
神梦流29 分钟前
GE 引擎的非标准数据流处理:稀疏张量与自定义算子在图优化中的语义保持
linux·运维·服务器
兜兜转转了多少年36 分钟前
从脚本到系统:2026 年 AI 代理驱动的 Shell 自动化
运维·人工智能·自动化
Lsir10110_1 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
Doro再努力2 小时前
【Linux操作系统12】Git版本控制与GDB调试:从入门到实践
linux·运维·服务器·git·vim
全栈工程师修炼指南2 小时前
Nginx | stream content 阶段:UDP 协议四层反向代理浅析与实践
运维·网络·网络协议·nginx·udp
Lsir10110_2 小时前
【Linux】进程信号(上半)
linux·运维·服务器
开开心心就好3 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
火车叼位3 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
迎仔4 小时前
06-存储设备运维进阶:算力中心的存储管家
运维
?re?ta?rd?ed?4 小时前
linux中的调度策略
linux·运维·服务器