×

负载均衡 负载

什么是负载均衡,为何要做负载均衡?在软件架构中,有哪些负载均衡它们起到的作用是什么

admin admin 发表于2022-07-30 23:11:44 浏览98 评论0

抢沙发发表评论

负载均衡不在发送请求到这台服务器上,负载均衡将用户(客户端)的访问平均地分配到每台服务器上,客户端负载均衡:服务端部署多台服务器,负载均衡认为该服务器状态不正常,为何要做负载均衡一、什么是负载均衡当单个节点的服务,可以分成两种:服务端负载均衡:调用方只访问负载均衡的IP,让同一个 IP 的请求始终路由到同一台服务器上,将不再发送请求到这台服务器上。

什么是负载均衡,为何要做负载均衡

一、什么是负载均衡

当单个节点的服务,无法支持当前的大量请求时,我们会部署多个节点,即所谓的集群,此时要使每个节点收到的请求均匀的算法,这个策略就是所谓的负载均衡了。

负载均衡

常见的负载均衡算法,有权重随机、Hash、轮询

1.权重随机

这个是最简单,也是最常用的负载均衡算法,即每个请求过来,会随机到任何一个服务节点上,主流的rpc框架Dubbo,默认使用基于权重随机算法。

2.Hash

可以将客服端即请求端的ip,通过hash计算,得到一个数值,再取服务节点数的模,分配到对应的服务节点上。

3.轮询

将请求按照顺序,依次分配到节点1、节点2、节点3等节点上,如此循环往复。

二、为什么要做负载均衡

想想如果没有负载均衡算法,我们的请求有可能都打到同一节点上,有可能将这个节点给打死,而其他节点的机器闲置着没有提供服务,浪费资源。所以这就是负载均衡算法存在的意义了,可以将请求合理分发到各个节点,实现真正意义上多个节点提供服务的效果。-负载

在软件架构中,有哪些负载均衡它们起到的作用是什么

如果项目的用户量少、访问量不大、数据量也不多的时候,一台服务器足以支撑,那么直接项目部署一套,直接访问使用就可以了,但是当用户和数据量不断增多,访问量(并发量)不断增加,一台服务器不在能够支撑业务的时候,就需要使用多台机器,设计高性能的集群来应对。-负载均衡

那么当我部署了多台服务器(这里假如是两台),那么调用方是如何访问的呢?服务方如何均衡访问的流量呢?这时候就需要引出负载均衡了。

负载均衡就是通过一定的策略,把用户的访问量均匀地转发给后端的服务器;负载均衡可以提高系统的服务能力和高可用性。

负载均衡分类

常见的负载均衡技术有三种:

  • DNS负载均衡:大概的原理是,当用户访问域名的时候,需要先通过DNS解析域名,找到对应的IP地址,在这个过程中,可以让DNS服务器,根据用户的地理位置,返回不同的IP,这样就可以实现负载均衡,同时也可以提升用户的访问速度。-负载

  • 软件负载均衡:用软件来实现流量的分发,有基于传输层实现的负载均衡,比如LVS,也有基于应用层来实现的,比如Nginx;软件负载均衡实现起来很简单,只需要在服务器上部署并进行配置就可以实现;

  • 硬件负载均衡:用硬件来实现负载均衡,比如F5(F5 Network Big-IP),这是一台网络设备,性能很高,同时价格非常的贵。

从另外一个角度对负载均衡进行分类,可以分成两种:

  • 服务端负载均衡:调用方只访问负载均衡的IP,不需要管后面有多少台服务器。

  • 客户端负载均衡:服务端部署多台服务器,客户端知道每台服务器的地址,并通过一定的路由规则,均衡地访问,比如Spring Cloud Ribbon,当然客户端的负载均衡,通常是需要服务注册发现的配合。

常见的负载均衡调度算法

  • 轮循(Round Robin):将请求循环分配给有效的服务器;

  • 加权轮循(Weighted Round Robin):轮训的升级版,给后端的服务器分配不同的权限,根据权重进行循环分配;比如A、B服务器权重分别是100和50,那么请求会保持2:1的比例进行分配;

  • 最少连接数(Least Connection):分配的请求根据每台服务器当前所打开的连接数来进行分配;

  • 源IP哈希(Source IP Hash):对调用方的IP进行HASH运算,并根据这个计算结果分配服务器,这样的好处是同一个主机的请求,始终会被同一个服务器响应(但是不一定均衡)。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。

要做负载均衡,代码要满足什么条件

当我们的程序只部署一套,不再能满足访问量(调用量)的时候,最简单的横向扩容的方法就是部署多套应用环境,负载均衡将用户(客户端)的访问平均地分配到每台服务器上,这样就可以利用多台机器的资源,增加系统的负载能力。-负载均衡

那么要做负载均衡,对我们的系统有什么要求么?或者说我们的代码需要做什么改造么?

大部分时候我们的代码是不需要改造的,但是也要注意这么几点。

我们的服务最好是无状态的,也就是每一次的调用,不依赖于前一次的调用结果,如果前后有依赖,则需要后面的请求携带着前一次请求的结果,作为参数进行访问。

除非负载均衡开启了会话保持,或者通过一些负载均衡路由策略,让同一个 IP 的请求始终路由到同一台服务器上,但是这并不是一个好的解决方案。

通常我们需要保持服务的无状态性,如果需要做权限认证的话,建议采用 Token 或使用 Redis 做 Session 共享(推荐使用 Token)。

还有一点,可能不一定必须的,不过我觉得也是个不错的方案,供大家参考。

假如我们有两台应用服务器 A 和 B,前面挂一台负载均衡,当我们需要做应用升级的话,通常可以怎么做?

  • 通常的办法是停掉服务器 A,这时候负载均衡会监控到这台服务器 A 已经无法使用了(比如监控到端口消失),再来的请求会发送给服务器 B;

  • 对服务器 A 升级并启动,负载均衡监控到 A 恢复了,会将请求发送给 A 和 B;

  • 对服务器 B 做相同的操作。

这样看似没有问题,因为在服务器升级的时候,负载均衡不在发送请求到这台服务器上;但是大家仔细想一想这个过程,如果在停服务器的那一刻,已经有请求进来了并进行处理,但是还没有返回,这时候停掉服务器,会导致这部分请求发生异常,那么这个问题如何解决呢?这就需要对程序进行一定的改造了。-负载

  • 应用提供一个接口,返回一个静态变量的值,只要 true 或 false 两个状态;

  • 负载均衡不再监控端口是否消失,而是监控剪口返回的状态,返回 true 表示应用正常,false 或没有返回表示不正常;

  • 每次停服务之前,通过接口修改当前应用静态变量的值为 false;

  • 负载均衡认为该服务器状态不正常,将不再发送请求到这台服务器上;

  • 等待几十秒,这段时间相当于等待当前请求都处理并返回,再停止服务。

“停止服务时,不再接受新的请求,等现有请求都处理完成后再真正停止服务”,这只是一个笨办法,想要避免以上问题还有更好的办法,并且对代码没有侵入性;有些中间件本身提供了类似的功能,我们只需执行对应的停止服务的命令即可;或者需要在代码中添加监听类,当收到 kill 信号的时候,拒绝新的请求,等待一段时间,再结束程序等等。-负载均衡

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。