负载均衡

负载均衡

负载均衡 指的是将用户请求分摊到不同的服务器上处理,以提高系统整体的并发处理能力以及可靠性。负载均衡服务可以有由专门的软件或者硬件来完成,一般情况下,硬件的性能更好,软件的价格更便宜

负载均衡可以简单分为服务端负载均衡和客户端负载均衡这两种,服务端负载均衡涉及到的知识点更多,工作中遇到的也比较多

image-20240428105956305

客户端负载均衡

客户端负载均衡主要应用于系统内部的不同的服务之间,可以使用现成的负载均衡组件来实现。

在客户端负载均衡中,客户端会自己维护一份服务器的地址列表,发送请求之前,客户端会根据对应的负载均衡算法来选择具体某一台服务器处理请求。

客户端负载均衡器和服务运行在同一个进程或者说 Java 程序里,不存在额外的网络开销。不过,客户端负载均衡的实现会受到编程语言的限制,比如说 Spring Cloud Load Balancer 就只能用于 Java 语言。

Java 领域主流的微服务框架 Dubbo、Spring Cloud 等都内置了开箱即用的客户端负载均衡实现。Dubbo属于是默认自带了负载均衡功能,Spring Cloud 是通过组件的形式实现的负载均衡,属于可选项,比较常用的是 Spring Cloud Load Balancer(官方,推荐)和 Ribbon(Netflix,已被启用)。

image-20240428110657224

服务端负载均衡

服务端负载均衡主要应用在 系统外部请求和网关层 之间,可以使用软件或者硬件实现

下图是一个简单的基于 Nginx 的服务端负载均衡示意图:

image-20240428110807064

硬件负载均衡通过专门的硬件设备(比如 F5、A10、Array )实现负载均衡功能。

硬件负载均衡的优势是性能很强且稳定,缺点就是实在是太贵了。像基础款的F5 最低也要 20 多万,绝大部分公司是根本负担不起的,业务量不大的话,真没必要非要去弄个硬件来做负载均衡,用软件负载均衡就足够了

在我们日常开发中,一般很难接触到硬件负载均衡,接触的比较多的还是软件负载均衡。软件负载均衡通过软件(比如 LVS、Nginx、HAproxy)实现负载均衡功能,性能虽然差一些,但价格便宜啊,像基础款的 Linux 服务器也就几千,性能好一点的 2~3 万的就很不错了。

根据 OSI 模型,服务端负载均衡还可以分为

  • 二层负载均衡
  • 三层负载均衡
  • 四层负载均衡
  • 七层负载均衡
image-20240428111005828

四层负载均衡 :工作在 OSI 模型第四层,也就是传输层,这一层的主要协议是 TCP/UDP,负载均衡器在这一层能够看到数据包里的源端口地址以及目的端口地址,会基于这些信息通过一定的负载均衡算法将数据包转发到后端真实服务器。

七层负载均衡:工作在 OSI 模型第七层,也就是应用层,这一层的主要协议是 HTTP 。这一层的负载均
衡比四层负载均衡路由网络请求的方式更加复杂,它会读取报文的数据部分(比如说我们的 HTTP 部分的报文),然后根据读取到的数据内容(如 URL、Cookie)做出负载均衡决策。

七层负载均衡比四层负载均衡会消耗更多的性能,不过,也相对更加灵活,能够更加智能地路由网络请求,比如说你可以根据请求的内容进行优化如缓存、压缩、加密。

简单来说,四层负载均衡性能更强,七层负载均衡功能更强。在工作中,我们通常会使用 Nginx 来做七层负载均衡,LVS(Linux Virtual Server 虚拟服务器,,Linux 内核的 4层负载均衡)来做四层负载均衡。

常见的负载均衡算法

随机法

随机法是最简单粗暴的负载均衡算法。

如果没有配置权重的话,所有的服务器被访问到的概率都是相同的。如果配置权重的话,权重越高的服务器被访问的概率就越大。

未加权重的随机算法适合于服务器性能相近的集群,其中每个服务器承载相同的负载。加权随机算法适合于服务器性能不等的集群,权重的存在可以使请求分配更加合理化。

不过,随机算法有一个比较明显的缺陷:部分机器在一段时间之内无法被随机到,毕竟是概率算法,就算是大家权重一样,也可能会出现这种情况。

轮询法

轮询法(Round Robin)是一种简单而常见的服务端负载均衡算法,其基本原理是按照顺序将请求依次分配给每个服务实例,每次请求选择下一个服务实例进行处理。这意味着每个服务实例都有机会处理请求,从而实现了基本的负载均衡。

如果没有配置权重的话,每个请求按时间顺序逐一分配到不同的服务器处理。如果配置权重的话,权重越高的服务器被访问的次数就越多。

未加权重的轮询算法适合于服务器性能相近的集群,其中每个服务器承载相同的负载。加权轮询算法适合于服务器性能不等的集群,权重的存在可以使请求分配更加合理化。

一致性Hash法

相同参数的请求总是发到同一台服务器处理,比如同个IP的请求

对于分布式存储,不同机器上存储不同对象的数据,我们使用哈希函数建立从数据到服务器之间的映射关系。

最小连接法

当有新的请求出现时,遍历服务器节点列表并选取其中活动连接数最小的一台服务器来响应当前请求。活动连接数可以理解为当前正在处理的请求数。

最小连接法可以尽可能最大地使请求分配更加合理化,提高服务器的利用率。不过,这种方法实现起来也最复杂,需要监控每一台服务器处理的请求连接数。

最少活跃法

最少活跃法和最小连接法类似,但要更科学一些。最少活跃法以活动连接数为标准,活动连接数可以理解为当前正在处理的请求数。活跃数越低,说明处理能力越强,这样就可以使处理能力强的服务器处理更多请求。相同活跃数的情况下,可以进行加权随机。

最快响应时间法

不同于最小连接法和最少活跃法,最快响应时间法以响应时间为标准来选择具体是哪一台服务器处理。客户端会维持每个服务器的响应时间,每次请求挑选响应时间最短的。相同响应时间的情况下,可以进行加权随机。

这种算法可以使得请求被更快处理,但可能会造成流量过于集中于高性能服务器的问题

七层负载均衡可以怎么做?

简单介绍两种项目中常用的七层负载均衡解决方案:DNS 解析和反向代理

除了我介绍的这两种解决方案之外,HTTP 重定向等手段也可以用来实现负载均衡,不过,相对来说,还是 DNS 解析和反向代理用的更多一些,也更推荐一些。

DNS解析

DNS 解析是比较早期的七层负载均衡实现方式,非常简单。

DNS 解析实现负载均衡的原理是这样的:在 DNS 服务器中为同一个主机记录配置多个 IP 地址,这些 IP地址对应不同的服务器。当用户请求域名的时候,DNS 服务器采用轮询算法返回IP 地址,这这样就实现了轮询版负载均衡。

image-20240428114911868

现在的 DNS 解析几乎都支持 IP 地址的权重配置,这样的话,在服务器性能不等的集群中请求分配会更加合理化。像我自己目前正在用的阿里云 DNS 就支持权重配置

反向代理

客户端将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器,获取数据后再返回给客户端。对外暴露的是反向代理服务器地址,隐藏了真实服务器 IP 地址。反向代理“代理”的是目标服务器这一个过程对于客户端而言是透明的。

Nginx 就是最常用的反向代理服务器,它可以将接收到的客户端请求以一定的规则(负载均衡策略)均匀地分配到这个服务器集群中所有的服务器上。

反向代理负载均衡同样属于七层负载均衡。

image-20240428115106088

客户端负载均衡通常是怎么做的?

Netflix Ribbon 和 Spring Cloud Load Balancer 就是目前 Java 生态最流行的两个负载均衡组件。
Ribbon 是老牌负载均衡组件,由 Netflix 开发,功能比较全面,支持的负载均衡策略也比较多。 SpringCloud Load Balancer 是 Spring 官方为了取代 Ribbon 而推出的,功能相对更简单一些,支持的负载均衡也少一些。

Ribbon 支持的 7种负载均衡策略:

  • RandomRule :随机策略。
  • RoundRobinRule(默认)轮询策略
  • WeightedResponseTimeRule:权重(根据响应时间决定权重)策略
  • BestAvailableRule:最小连接数策略
  • RetryRule:重试策略(按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null)
  • AvailabilityFilteringRule:可用敏感性策略(先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例)
  • ZoneAvoidanceRule:区域敏感性策略(根据服务所在区域的性能和服务的可用性来选择服务实例)

Spring Cloud Load Balancer 支持的 2 种负载均衡策略:

  • RandomLoadBalancer:随机策略
  • RoundRobinLoadBalancer(默认):轮询策略
image-20240428115453033

不过,Spring Cloud Load Balancer 支持的负载均衡策略其实不止这两种,ServiceInstanceListsupplier 的实现类同样可以让其支持类似于 Ribbon 的负载均衡策略。这个应该是后续慢慢完善引入的,不看官方文档还真发现不了,所以说阅读官方文档真的很重要


负载均衡
http://example.com/2024/03/25/项目/微服务/负载均衡/
作者
PALE13
发布于
2024年3月25日
许可协议