百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

一文精通现代网络负载均衡和代理(网络负载均衡的作用)

off999 2025-03-19 15:39 19 浏览 0 评论


现代网络负载平衡和代理简介


最近引起我注意的是,缺乏关于现代网络负载平衡和代理的介绍性教育材料。我心想:这怎么可能?负载均衡是构建可靠分布式系统所需的核心概念之一。肯定有可用的质量信息吗?我搜了一下,发现采摘确实很少。关于负载平衡和代理服务器的 Wikipedia 文章包含一些概念的概述,但不是对该主题的流畅处理,特别是因为它与现代微服务架构有关。谷歌搜索负载平衡主要会出现大量流行语和细节的供应商页面。

在这篇文章中,我试图通过简要介绍现代网络负载平衡和代理来纠正信息不足的问题。坦率地说,这是一个庞大的话题,可能会成为整本书的主题。为了保持这篇文章(有点)博客的长度,我尝试将一组复杂的主题提炼成一个简单的概述;根据兴趣和反馈,我将在稍后考虑有关各个主题的更详细的后续帖子。

关于我为什么写这篇文章的一些背景知识——我们开始吧!

什么是网络负载平衡和代理?

维基百科将负载平衡定义为:

在计算中,负载平衡改善了跨多个计算资源(例如计算机、计算机集群、网络链接、中央处理单元或磁盘驱动器)的工作负载分布。负载平衡旨在优化资源使用、最大化吞吐量、最小化响应时间并避免任何单个资源的过载。使用具有负载平衡的多个组件而不是单个组件可以通过冗余提高可靠性和可用性。负载平衡通常涉及专用的软件或硬件,例如多层交换机或域名系统服务器进程。

上述定义适用于计算的所有方面,而不仅仅是网络。操作系统使用负载均衡跨物理处理器调度任务,Kubernetes 等容器编排器使用负载均衡跨计算集群调度任务,网络负载均衡器使用负载均衡跨可用后端调度网络任务。本文的其余部分将仅涉及网络负载平衡

图 1:网络负载平衡概览

图 1显示了网络负载平衡的高级概述。一些客户端正在从一些后端请求资源。负载均衡器位于客户端和后端之间,并在较高级别执行几个关键任务:

  • 服务发现:系统中有哪些可用的后端?它们的地址是什么(即负载均衡器应该如何与它们通信)?
  • 健康检查:哪些后端目前是健康的并且可以接受请求?
  • 负载平衡:应该使用什么算法来平衡健康后端的单个请求?

在分布式系统中正确使用负载平衡有几个好处:

  • 命名抽象:不是每个客户端都需要了解每个后端(服务发现),客户端可以通过预定义的机制寻址负载均衡器,然后可以将名称解析的行为委托给负载均衡器。预定义的机制包括内置库和众所周知的 DNS/IP/端口位置,将在下面更详细地讨论。
  • 容错:通过健康检查和各种算法技术,负载均衡器可以有效地绕过坏的或过载的后端。这意味着操作员通常可以在闲暇时修复坏的后端,而不是在紧急情况下修复。
  • 成本和性能优势:分布式系统网络很少是同质的。该系统可能跨越多个网络区域和区域。在一个区域内,网络通常以相对不足的方式构建。在区域之间,超额认购成为常态。(在这种情况下,过度/不足是指通过 NIC 消耗的带宽量占路由器之间可用带宽的百分比)。智能负载均衡可以尽可能地将请求流量保持在区域内,从而提高性能(减少延迟)并降低整体系统成本(减少区域之间所需的带宽和光纤)。

负载均衡器与代理

在谈论网络负载均衡器时,负载均衡器代理这两个术语在业内大致可以互换使用。这篇文章还将这些术语视为一般等效。(学究式地,并非所有代理都是负载均衡器,但绝大多数代理将负载均衡作为主要功能)。

有些人可能还争辩说,当负载平衡作为嵌入式客户端库的一部分完成时,负载平衡器并不是真正的代理。然而,我认为这种区别给一个已经令人困惑的话题增加了不必要的复杂性。下面详细讨论负载均衡器拓扑的类型,但本文将嵌入式负载均衡器拓扑视为代理的一种特殊情况;应用程序通过嵌入式库进行代理,该库提供与应用程序进程之外的负载平衡器相同的抽象。

L4(连接/会话)负载均衡

在当今讨论整个行业的负载平衡时,解决方案通常分为两类:L4L7。这些类别指的是OSI 模型的第4层和第 7 层。由于在我讨论 L7 负载平衡时将变得显而易见的原因,我认为这些是我们使用的术语是不幸的。OSI 模型对负载平衡解决方案的复杂性的近似性非常差,这些解决方案包括传统的第 4 层协议,例如 TCP 和 UDP,但通常最终会在各种不同的 OSI 层中包含一些零碎的协议。即,如果 L4 TCP 负载均衡器也支持 TLS 终止,那么它现在是 L7 负载均衡器吗?

图 2:TCP L4 终止负载平衡

图 2显示了一个传统的 L4 TCP负载平衡器。在这种情况下,客户端与负载均衡器建立 TCP 连接。负载均衡器终止连接(即直接响应 SYN),选择一个后端,并与后端建立一个新的 TCP 连接(即发送一个新的 SYN)。该图的细节并不重要,将在下面专门讨论 L4 负载平衡的部分中详细讨论。

本节的主要内容是 L4 负载均衡器通常仅在 L4 TCP/UDP 连接/会话级别运行。因此负载均衡器粗略地来回打乱字节,并确保来自同一会话的字节在同一后端结束。L4 负载均衡器不知道它正在洗牌的字节的任何应用程序详细信息。字节可以是 HTTP、Redis、MongoDB 或任何其他应用程序协议。

L7(应用)负载均衡

L4 负载均衡很简单,仍然被广泛使用。L4负载均衡有哪些缺点值得投资L7(应用)负载均衡?以下面的 L4 具体案例为例:

  • 两个gRPC / HTTP2客户端想要与后端通信,因此它们通过 L4 负载均衡器连接。
  • L4 负载均衡器为每个传入 TCP 连接建立一个传出 TCP 连接,从而产生两个传入和两个传出连接。
  • 但是,客户端 A 每分钟通过其连接发送 1 个请求 (RPM),而客户端 B 通过其连接每秒发送 50 个请求 (RPS)。

在前面的场景中,选择处理客户端 A 的后端将处理大约 3000 倍的负载,然后选择处理客户端 B 的后端!这是一个很大的问题,通常首先会破坏负载平衡的目的。另请注意,任何多路复用保持活动的协议都会发生此问题。(多路复用意味着通过单个 L4 连接发送并发应用程序请求,保持活动意味着在没有活动请求时不关闭连接)。出于效率原因,所有现代协议都在发展为多路复用和保持活动(创建连接通常很昂贵,尤其是在使用 TLS 加密连接时),因此 L4 负载平衡器阻抗不匹配随着时间的推移变得更加明显。L7 负载均衡器解决了这个问题。

图 3:HTTP/2 L7 终止负载均衡

图 3显示了一个 L7 HTTP/2 负载平衡器。在这种情况下,客户端与负载均衡器建立一个 HTTP/2 TCP 连接。然后负载均衡器继续进行两个后端连接。当客户端向负载均衡器发送两个 HTTP/2 流时,流 1 被发送到后端 1,而流 2 被发送到后端 2。因此,即使是请求负载差异很大的多路复用客户端也将在后端之间得到有效平衡。这就是为什么 L7 负载平衡对于现代协议如此重要的原因。(由于 L7 负载平衡能够检查应用程序流量,它会产生大量额外的好处,但这将在下面更详细地介绍)。

L7 负载均衡和 OSI 模型

正如我在上面关于 L4 负载均衡的部分所说,使用 OSI 模型来描述负载均衡特性是有问题的。原因是 L7,至少正如 OSI 模型所描述的,它本身包含多个离散的负载平衡抽象层。例如,对于 HTTP 流量,请考虑以下子层:

  • 可选传输层安全 (TLS)。请注意,网络人士争论 TLS 属于哪个 OSI 层。为了便于讨论,我们将考虑 TLS L7。
  • 物理 HTTP 协议(HTTP/1 或 HTTP/2)。
  • 逻辑 HTTP 协议(标头、正文数据和尾部)。
  • 消息传递协议(gRPC、REST 等)。

复杂的 L7 负载均衡器可能会提供与上述每个子层相关的功能。另一个 L7 负载均衡器可能只有一小部分功能将其置于 L7 类别中。简而言之,从功能比较的角度来看,L7 负载均衡器环境比 L4 类别复杂得多。(当然,本节刚刚谈到了 HTTP;Redis、Kafka、MongoDB 等都是受益于 L7 负载均衡的 L7 应用程序协议的示例)。

负载均衡器功能

在本节中,我将简要总结负载均衡器提供的高级功能。并非所有负载均衡器都提供所有功能。

服务发现

服务发现是负载均衡器确定可用后端集的过程。方法多种多样,一些例子包括:

  • 静态配置文件。
  • 域名系统。
  • Zookeeper , Etcd , Consul等
  • Envoy 的通用数据平面 API。

健康检查

运行状况检查是负载均衡器确定后端是否可用于服务流量的过程。健康检查一般分为两类:

  • 活动:负载均衡器定期/healthcheck向后端发送 ping(例如,对端点的 HTTP 请求),并使用它来衡量健康状况。
  • 被动:负载均衡器从主要数据流中检测健康状态。例如,如果连续出现三个连接错误,L4 负载均衡器可能会判定后端不健康。如果连续出现三个 HTTP 503 响应代码,L7 负载均衡器可能会判定后端运行状况不佳。

负载均衡

是的,负载平衡器必须实际平衡负载!给定一组健康的后端,如何选择将服务于连接或请求的后端?负载平衡算法是一个活跃的研究领域,范围从随机选择和轮询等简单的算法,到考虑可变延迟和后端负载的更复杂的算法。鉴于其性能和简单性,最流行的负载平衡算法之一被称为2 最小请求负载平衡的幂。

粘性会话

在某些应用程序中,对同一会话的请求到达同一后端非常重要。这可能与缓存、临时复杂构造状态等有关。会话的定义各不相同,可能包括 HTTP cookie、客户端连接的属性或其他一些属性。许多 L7 负载均衡器都支持粘性会话。顺便说一句,我会注意到会话粘性本质上是脆弱的(托管会话的后端可能会死掉),因此在设计依赖它们的系统时建议谨慎。

TLS 终止

TLS 的主题及其在边缘服务和保护服务到服务通信中的作用值得单独发帖。话虽如此,许多 L7 负载均衡器会执行大量 TLS 处理,包括终止、证书验证和固定、使用SNI提供证书等。

可观察性

正如我在演讲中喜欢说的:“可观察性、可观察性、可观察性。” 网络本质上是不可靠的,负载均衡器通常负责导出统计信息、跟踪和日志,以帮助操作员找出问题所在,从而解决问题。负载均衡器的可观察性输出差异很大。最先进的负载均衡器提供丰富的输出,包括数字统计、分布式跟踪和可定制的日志记录。我要指出,增强的可观察性不是免费的。负载均衡器必须做额外的工作才能产生它。但是,数据的好处大大超过了相对较小的性能影响。

安全性和 DoS 缓解

尤其是在边缘部署拓扑中(见下文),负载均衡器经常实现各种安全功能,包括速率限制、身份验证和 DoS 缓解(例如,IP 地址标记和识别、缓送等)。

配置和控制平面

需要配置负载均衡器。在大型部署中,这可能成为一项艰巨的任务。通常,配置负载均衡器的系统被称为“控制平面”,并且在其实现中存在很大差异。有关此主题的更多信息,请参阅我关于服务网格数据平面与控制平面的帖子。

还有更多

本节刚刚介绍了负载均衡器提供的功能类型的表面。更多讨论可以在下面的 L7 负载均衡器部分找到。

负载均衡器拓扑的类型

既然我已经对负载均衡器是什么、L4 和 L7 负载均衡器之间的区别以及负载均衡器功能的总结进行了高级概述,我将继续讨论部署负载均衡器的各种分布式系统拓扑。(以下每种拓扑都适用于 L4 和 L7 负载均衡器)。

中间代理

图 4:中间代理负载均衡拓扑

图 4所示的中间代理拓扑可能是大多数读者最熟悉的获得负载平衡的方式。此类别包括来自 Cisco、Juniper、F5 等的硬件设备;亚马逊的ALB 和 NLB以及谷歌的Cloud Load Balancer等云软件解决方案;以及HAProxy、NGINX、Envoy等纯软件自托管解决方案. 中间代理解决方案的优点是用户简单。通常,用户通过 DNS 连接到负载均衡器,无需担心其他任何事情。中间代理解决方案的缺点是代理(即使是集群的)是单点故障以及扩展瓶颈。中间代理通常也是一个使操作变得困难的黑匣子。客户端中是否存在观察到的问题?在物理网络中?在中间代理?在后端?这可能很难说。

边缘代理

图 5:边缘代理负载平衡拓扑

边缘代理拓扑如图5所示实际上只是中间代理拓扑的一种变体,其中负载均衡器可通过 Internet 访问。在这种情况下,负载均衡器通常必须提供额外的“API 网关”功能,例如 TLS 终止、速率限制、身份验证和复杂的流量路由。边缘代理的优缺点与中间代理相同。需要注意的是,在面向 Internet 的大型分布式系统中部署专用边缘代理通常是不可避免的。客户端通常需要使用服务所有者无法控制的任意网络库通过 DNS 访问系统(使以下部分中描述的嵌入式客户端库或 sidecar 代理拓扑无法直接在客户端上运行)。此外,

嵌入式客户端库

图 6:通过嵌入式客户端库进行负载平衡

为了避免中间代理拓扑中固有的单点故障和扩展问题,更复杂的基础设施已经转向通过库将负载均衡器直接嵌入到服务中,如图 6所示。库支持的功能差异很大,但该类别中一些最著名且功能最丰富的库是Finagle、Eureka/Ribbon/Hystrix和gRPC(大致基于名为 Stubby 的内部 Google 系统)。基于库的解决方案的主要优点是它将负载均衡器的所有功能完全分配给每个客户端,从而消除了前面描述的单点故障和扩展问题。基于库的解决方案的主要缺点是必须以组织使用的每种语言来实现库。分布式架构正变得越来越“多语言”(多语言)。在这种环境下,用许多不同的语言重新实现一个极其复杂的网络库的成本可能会变得过高。最后,跨大型服务架构部署库升级可能会非常痛苦,这使得库的许多不同版本很可能会在生产环境中同时运行,

综上所述,上述库对于能够限制编程语言扩散并克服库升级难题的公司来说是成功的。

边车代理

图 7:通过 sidecar 代理进行负载平衡

嵌入式客户端库负载平衡器拓扑的一个变体是边车代理拓扑,如图 7所示。近年来,这种拓扑已被普及为“服务网格”。Sidecar 代理背后的想法是,通过跳转到不同的进程会带来轻微的延迟损失,嵌入式库方法的所有好处都可以在没有任何编程语言锁定的情况下获得。在撰写本文时,最流行的 sidecar 代理负载均衡器是Envoy、NGINX、HAProxy和Linkerd。有关 sidecar 代理方法的更详细处理,请参阅我的介绍 Envoy 的博客文章以及我的在服务网格数据平面与控制平面上发布。

不同负载均衡器拓扑的总结和优缺点

  • 中间代理拓扑通常是最容易使用的负载平衡拓扑。由于是单点故障、扩展限制和黑盒操作,它的不足之处。
  • 边缘代理拓扑类似于中间代理,但通常无法避免。
  • 嵌入式客户端库拓扑提供了最佳的性能和可扩展性,但需要以每种语言实现库以及需要在所有服务中升级库。
  • Sidecar 代理拓扑的性能不如嵌入式客户端库拓扑,但不受任何限制。

总的来说,我认为 Sidecar 代理拓扑(服务网格)将逐渐取代所有其他服务到服务通信的拓扑。在流量进入服务网格之前,总是需要边缘代理拓扑。

L4 负载平衡的最新技术

L4 负载均衡器是否仍然相关?

这篇文章已经讨论了 L7 负载均衡器对于现代协议有多么出色,并将在下面更详细地介绍 L7 负载均衡器功能。这是否意味着 L4 负载均衡器不再相关?不!尽管在我看来,L7 负载均衡器最终将完全取代 L4 负载均衡器进行服务间通信,但 L4 负载均衡器在边缘仍然非常重要,因为几乎所有现代大型分布式架构都使用两层 L4/L7 负载均衡架构用于互联网流量。在边缘部署中将专用 L4 负载平衡器放在 L7 负载平衡器之前的好处是:

  • 由于 L7 负载均衡器对应用程序流量执行更复杂的分析、转换和路由,因此与优化的 L4 负载均衡器相比,它们可以处理相对较小部分的原始流量负载(以每秒数据包和每秒字节数衡量)。这一事实通常使 L4 负载平衡器成为处理某些类型的 DoS 攻击(例如,SYN 泛洪、通用数据包泛洪攻击等)的更好位置。
  • L7 负载均衡器往往比 L4 负载均衡器更积极地开发、更频繁地部署并且具有更多错误。与现代 L4 负载平衡器使用的部署机制相比,现代 L4 负载平衡器通常使用 BGP 和 ECMP(下面将详细介绍),在前面放置一个可以在 L7 负载平衡器部署期间进行健康检查和排空的 L4 负载平衡器要容易得多。最后,由于 L7 负载均衡器更有可能纯粹由于其功能的复杂性而出现错误,因此拥有可以绕过故障和异常的 L4 负载均衡器会导致整个系统更加稳定。

在以下部分中,我将描述中间/边缘代理 L4 负载均衡器的几种不同设计。以下设计一般不适用于客户端库和 Sidecar 代理拓扑。

TCP/UDP 终止负载平衡器

图 8:L4 终端负载均衡器

仍在使用的第一种类型的 L4 负载均衡器是图 8所示的终端负载均衡器。这与我们在上面介绍 L4 负载均衡时看到的负载均衡器相同。在这种类型的负载均衡器中,使用了两个离散的 TCP 连接:一个在客户端和负载均衡器之间,一个在负载均衡器和后端之间。

仍然使用 L4 终止负载均衡器有两个原因:

  1. 它们实施起来相对简单。
  2. 靠近客户端(低延迟)的连接终止对性能有很大影响。具体而言,如果终端负载平衡器可以放置在靠近使用有损网络(例如蜂窝网络)的客户端附近,则在将数据移动到可靠的光纤传输途中到达其最终位置之前,重传可能会更快发生。换句话说,这种类型的负载均衡器可能用于存在点 (POP) 场景中以终止原始 TCP 连接。

TCP/UDP 直通负载平衡器

图 9:L4 直通负载均衡器

第二种 L4 负载均衡器是图 9所示的直通负载均衡器。在这种类型的负载均衡器中,负载均衡器不会终止TCP 连接。相反,每个连接的数据包在连接跟踪和网络地址转换 ( NAT ) 发生后被转发到选定的后端。首先,让我们定义连接跟踪和 NAT:

  • 连接跟踪:是跟踪所有活动 TCP 连接状态的过程。这包括诸如握手是否完成、是否收到 FIN、连接空闲多长时间、为连接选择了哪个后端等数据。
  • NAT : NAT 是使用连接跟踪数据在数据包通过负载平衡器时更改数据包的 IP/端口信息的过程。

使用连接跟踪和 NAT,负载均衡器可以将大部分原始 TCP 流量从客户端传递到后端。例如,假设客户端正在与之交谈,1.2.3.4:80并且选定的后端位于10.0.0.2:9000. 客户端 TCP 数据包将在1.2.3.4:80. 然后负载平衡器将交换数据包的目标 IP 和端口10.0.0.2:9000。它还将数据包的源 IP 与负载均衡器的 IP 地址交换。因此,当后端响应 TCP 连接时,数据包将返回到负载平衡器,在此进行连接跟踪,并且 NAT 可以在相反方向再次发生。

为什么要使用这种类型的负载均衡器来代替上一节中描述的终端负载均衡器,因为它更复杂?几个原因:

  • 性能和资源使用:因为直通负载均衡器不会终止 TCP 连接,所以它们不需要缓冲任何 TCP 连接窗口。每个连接存储的状态量非常小,通常通过高效的哈希表查找来访问。因此,直通负载平衡器通常可以处理比终止负载平衡器更多的活动连接和每秒数据包 (PPS)。
  • 允许后端执行自定义的拥塞控制:TCP 拥塞控制是 Internet 上的端点限制发送数据的机制,以免占用可用带宽和缓冲区。由于直通负载均衡器不会终止 TCP 连接,因此它不参与拥塞控制。这一事实允许后端根据其应用程序用例使用不同的拥塞控制算法。它还允许对拥塞控制更改进行更轻松的实验(例如,最近的BBR推出)。
  • 形成直接服务器返回 (DSR) 和集群 L4 负载平衡的基线:更高级的 L4 负载平衡技术需要直通负载平衡,例如 DSR 和具有分布式一致性哈希的集群(在以下部分中讨论)。

直接服务器返回 (DSR)

图 10:L4 直接服务器返回 (DSR)

图 10显示了直接服务器返回 (DSR) 负载平衡器。DSR 建立在上一节中描述的直通负载平衡器之上。DSR 是一种优化,其中只有入口/请求数据包遍历负载均衡器。出口/响应数据包绕过负载均衡器直接返回客户端。执行 DSR 有趣的主要原因是在许多工作负载中,响应流量使请求流量相形见绌(例如,典型的 HTTP 请求/响应模式)。假设 10% 的流量是请求流量,90% 的流量是响应流量,如果 DSR 正在使用1/10的负载均衡器的容量可以满足系统的需要。由于历史上负载平衡器非常昂贵,因此这种类型的优化会对系统成本和可靠性产生重大影响(越少越好)。DSR 负载均衡器通过以下方式扩展了直通负载均衡器的概念:

  • 负载均衡器通常仍然执行部分连接跟踪。由于响应数据包不会遍历负载均衡器,因此负载均衡器不会知道完整的 TCP 连接状态。但是,负载均衡器可以通过查看客户端数据包并使用各种类型的空闲超时来强烈推断状态。
  • 负载均衡器通常使用通用路由封装 ( GRE ) 来封装从负载均衡器发送到后端的 IP 数据包,而不是 NAT。这样,当后端收到封装后的数据包时,就可以对其进行解封装,并知道客户端的原始IP地址和TCP端口。这允许后端直接响应客户端,而无需响应数据包流经负载均衡器。
  • DSR负载均衡器的一个重要部分是后端参与负载均衡。后端需要有一个正确配置的 GRE 隧道,并且根据网络设置的底层细节可能需要它自己的连接跟踪、NAT 等。

请注意,在直通负载均衡器和 DSR 负载均衡器设计中,可以通过多种方式跨负载均衡器和后端设置连接跟踪、NAT、GRE 等。不幸的是,该主题超出了本文的范围。

通过高可用性对容错

图 11:通过 HA 对和连接跟踪的 L4 容错

到目前为止,我们一直在孤立地考虑 L4 负载均衡器的设计。直通和 DSR 负载均衡器都需要负载均衡器本身的一些连接跟踪和状态。如果负载均衡器死了怎么办?如果负载均衡器的单个实例死机,则遍历负载均衡器的所有连接都将被切断。根据应用程序,这可能会对应用程序性能产生重大影响。

从历史上看,L4 负载均衡器是从典型供应商(Cisco、Juniper、F5 等)购买的硬件设备。这些设备非常昂贵并且处理大量流量。为了避免单个负载均衡器故障切断所有连接并导致大量应用程序中断,负载均衡器通常部署在高可用性对中,如图 11所示。典型的 HA 负载平衡器设置具有以下设计:

  • 一对 HA 边缘路由器为一定数量的虚拟 IP ( VIP ) 提供服务。这些边缘路由器使用边界网关协议 ( BGP ) 宣布 VIP。主边缘路由器具有比备份更高的 BGP 权重,因此在稳定状态下它为所有流量提供服务。(BGP 是一种极其复杂的协议;就本文而言,仅将 BGP 视为一种机制,网络设备通过该机制宣布它们可以从其他网络设备获取流量,并且每个链路都可以有一个权重来确定链路流量的优先级)。
  • 类似地,主 L4 负载均衡器向边缘路由器宣布其自身具有比备份更高的 BGP 权重,因此在稳定状态下它为所有流量提供服务。
  • 主负载均衡器与备份交叉连接,并共享其所有连接跟踪状态。因此,如果主节点死机,备份节点可以接管所有活动连接。
  • 两个边缘路由器和两个负载均衡器都是交叉连接的。这意味着,如果其中一台边缘路由器或一台负载均衡器死机,或者其 BGP 公告由于某种其他原因而被撤销,则备份可以接管所有流量的服务。

上面的设置是今天仍然服务的高流量互联网应用程序的数量。但是,上述方法有很大的缺点:

  • 考虑到容量使用情况,VIP 必须在 HA 负载均衡器对之间正确分片。如果单个 VIP 超出单个 HA 对的容量,则需要将 VIP 拆分为多个 VIP。
  • 系统资源利用率低。50% 的容量在稳定状态下处于空闲状态。鉴于历史上硬件负载均衡器非常昂贵,这会导致大量闲置资金。
  • 现代分布式系统设计比主动/备份提供更大的容错能力。例如,最佳情况下,系统应该能够同时遭受多个故障并继续运行。如果活动负载平衡器和备用负载平衡器同时死亡,则 HA 负载平衡器对很容易出现完全故障。
  • 来自供应商的专有大型硬件设备非常昂贵,并导致供应商锁定。通常希望用使用商品计算服务器构建的水平可扩展软件解决方案替换这些硬件设备。

通过具有分布式一致性哈希的集群进行容错和扩展

图 12:通过集群负载均衡器和一致散列的 L4 容错和扩展

上一节介绍了通过 HA 对的 L4 负载均衡器容错以及该设计中固有的问题。从 2000 年代初到中期,大型互联网基础设施开始设计和部署新的大规模并行 L4 负载平衡系统,如图 12所示。这些系统的目标是:

  • 减轻上一节中描述的 HA 对设计的所有缺点。
  • 从供应商的专有硬件负载平衡器转向使用标准计算服务器和 NIC 构建的商品软件解决方案。

这种 L4 负载平衡器设计最好称为容错和通过集群和分布式一致性散列进行扩展。它的工作原理如下:

  • N 个边缘路由器以相同的 BGP 权重宣布所有任播VIP。等价多路径路由 ( ECMP ) 通常用于确保来自单个的所有数据包到达同一边缘路由器。流通常是源 IP/端口和目标 IP/端口的 4 元组。(简而言之,ECMP 是一种使用一致散列在一组具有相同权重的网络链路上分发数据包的方法)。尽管边缘路由器本身并不特别关心哪些数据包到达哪里,但一般来说,来自一个流的所有数据包最好遍历同一组链路,以避免出现降低性能的乱序数据包。
  • N L4 负载平衡器机器以相同的 BGP 权重向边缘路由器宣布所有 VIP。再次使用 ECMP,边缘路由器通常会为流选择相同的负载平衡器机器。
  • 每个 L4 负载均衡器机器通常会执行部分连接跟踪,然后使用一致的哈希来为流选择一个后端。GRE 用于封装从负载均衡器发送到后端的数据包。
  • 然后使用 DSR 通过边缘路由器将数据包从后端直接发送到客户端。
  • L4 负载均衡器使用的实际一致哈希算法是一个积极研究的领域。主要围绕均衡负载、最小化延迟、最小化后端更改期间的中断
    以及最小化内存开销进行权衡。对该主题的完整讨论超出了本文的范围。

让我们看看上述设计如何减轻 HA 对方法的所有缺点:

  • 可以根据需要添加新的边缘路由器和负载平衡器机器。在每一层都使用一致的散列,以在添加新机器时尽可能减少受影响的流的数量。
  • 在保持足够的突发裕度和容错能力的同时,系统的资源使用率可以随心所欲地运行。
  • 边缘路由器和负载均衡器现在都可以使用商用硬件构建,成本只是传统硬件负载均衡器的一小部分(更多内容见下文)。

关于这种设计的一个典型问题是“为什么边缘路由器不通过 ECMP 直接与后端通信?为什么我们需要负载均衡器?” 其原因主要是围绕 DoS 缓解和后端操作简便性。如果没有负载均衡器,每个后端都必须参与 BGP,并且执行滚动部署会变得更加困难。

所有现代 L4 负载平衡系统都在朝着这种设计(或它的一些变体)发展。两个最著名的众所周知的例子是来自谷歌的Maglev和来自亚马逊的网络负载均衡器 (NLB) 。目前没有任何 OSS 负载均衡器实现了这种设计,但是,据我所知,有一家公司计划在 2018 年向 OSS 发布一个。我对这个版本感到非常兴奋,因为现代 L4 负载均衡器是一个关键部分网络空间中缺少 OSS。

L7 负载平衡的最新技术

确实是的。在过去的几年里,L7 负载均衡器/代理开发出现了复苏。这与分布式系统中微服务架构的持续推进非常吻合。从根本上说,当使用得更频繁时,固有故障网络变得更加难以有效运行。此外,自动缩放、容器调度程序等的兴起意味着在静态文件中配置静态 IP 的日子已经一去不复返了。系统不仅更多地利用网络,而且变得更加动态,需要负载平衡器中的新功能。在本节中,我将简要总结现代 L7 负载均衡器中发展最快的领域。

协议支持

现代 L7 负载均衡器正在增加对许多不同协议的显式支持。负载均衡器对应用程序流量的了解越多,它在可观察性输出、高级负载均衡和路由等方面可以做的事情就越复杂。例如,在撰写本文时,Envoy 明确支持 L7 协议解析和路由适用于 HTTP/1、HTTP2、gRPC、Redis、MongoDB 和 DynamoDB。未来可能会添加更多协议,包括 MySQL 和 Kafka。

动态配置

如上所述,分布式系统日益动态的特性要求在创建动态和反应控制系统方面进行并行投资。Istio就是这种系统的一个例子。有关此主题的更多信息,请参阅我关于服务网格数据平面与控制平面的帖子。

高级负载平衡

L7 负载均衡器现在通常具有对高级负载均衡功能的内置支持,例如超时、重试、速率限制、断路、阴影、缓冲、基于内容的路由等。

可观察性

如上面关于一般负载平衡器功能的部分所述,正在部署的日益动态的系统变得越来越难以调试。健壮的协议特定的可观察性输出可能是现代 L7 负载均衡器提供的最重要的功能。现在几乎所有 L7 负载平衡解决方案都需要输出数字统计信息、分布式跟踪和可自定义的日志记录。

可扩展性

现代 L7 负载均衡器的用户通常希望轻松扩展它们以添加自定义功能。这可以通过编写加载到负载平衡器中的可插入过滤器来完成。许多负载均衡器也支持脚本,通常通过Lua。

容错

我在上面写了很多关于 L4 负载均衡器容错的文章。L7 负载均衡器的容错能力如何?通常,我们将 L7 负载均衡器视为可消耗且无状态的。使用商品软件可以轻松地水平扩展 L7 负载均衡器。此外,L7 负载均衡器执行的处理和状态跟踪比 L4 复杂得多。尝试构建 L7 负载均衡器的 HA 配对在技术上是可行的,但这将是一项艰巨的任务。

总体而言,在 L4 和 L7 负载平衡域中,行业正在从 HA 配对转向通过一致哈希收敛的水平可扩展系统。

和更多

L7 负载均衡器正在以惊人的速度发展。有关 Envoy 提供的示例,请参阅 Envoy 的架构概述。

全局负载均衡和集中控制平面

图 13:全局负载均衡

负载均衡的未来将越来越多地将单个负载均衡器视为商品设备。在我看来,真正的创新和商业机会都在控制平面内。图 13显示了一个全局负载平衡系统的示例。在这个例子中,发生了一些不同的事情:

  • 每个 sidecar 代理都与三个不同区域(A、B 和 C)中的后端通信。
  • 如图所示,90% 的流量被发送到区域 C,而 5% 的流量被发送到区域 A 和 B。
  • Sidecar 代理和后端都定期向全局负载均衡器报告状态。这允许全局负载均衡器做出考虑延迟、成本、负载、当前故障等的决策。
  • 全局负载均衡器定期为每个 Sidecar 代理配置当前路由信息。

全局负载均衡器将越来越能够完成单个负载均衡器无法单独完成的复杂事情。例如:

  • 自动检测和绕过区域故障。
  • 应用全局安全和路由策略。
  • 使用机器学习和神经网络检测和缓解流量异常,包括 DDoS 攻击。
  • 提供集中的 UI 和可视化,使工程师能够总体理解和操作整个分布式系统。

为了使全局负载均衡成为可能,用作数据平面的负载均衡器必须具有复杂的动态配置能力。有关此主题的更多信息,请参阅我关于Envoy 的通用数据平面 API以及服务网格数据平面与控制平面的帖子。

从硬件到软件的演变

到目前为止,这篇文章只简单地提到了硬件与软件,主要是在历史 L4 负载均衡器 HA 对的背景下。该领域的行业趋势是什么?

上一条推文是一种幽默的夸张,但仍然很好地总结了趋势,它们是:

  • 从历史上看,路由器和负载平衡器是作为极其昂贵的专有硬件提供的。
  • 越来越多的专有 L3/L4 网络设备正在被商品服务器硬件、商品 NIC 和构建在IPVS、DPDK和fd.io等框架之上的专用软件解决方案所取代。使用 Linux 和使用 DPDK 编写的自定义用户空间应用程序,成本低于 5000 美元的现代数据中心机器可以轻松地用非常小的数据包使 80Gbps NIC 饱和。与此同时,能够以惊人的总带宽和数据包速率进行 ECMP 路由的廉价和基本路由器/交换机 ASIC 正在被打包为商品路由器。
  • NGINX、HAProxy 和 Envoy 等复杂的 L7 软件负载均衡器也在快速迭代和蚕食以前 F5 等供应商的领域。因此,L7 负载均衡器也在积极转向商品软件解决方案。
  • 同时,整个行业向 IaaS、CaaS 和 FaaS 的转变以及主要云提供商的推动意味着越来越少的工程师需要了解物理网络的工作原理(这些是“黑魔法”和“我们不再需要知道的东西”部分)。

结论和负载均衡的未来

总而言之,这篇文章的主要内容是:

  • 负载均衡器是现代分布式系统中的关键组件。
  • 负载均衡器一般分为两类:L4 和 L7。
  • L4 和 L7 负载均衡器都与现代架构相关。
  • L4 负载均衡器正在向水平可扩展的分布式一致性哈希解决方案发展。
  • 由于动态微服务架构的激增,最近对 L7 负载均衡器进行了大量投资。
  • 全局负载均衡以及控制平面和数据平面之间的分离是负载均衡的未来,也是未来大部分创新和商业机会的所在。
  • 该行业正在积极转向用于网络解决方案的商品 OSS 硬件和软件。我相信像 F5 这样的传统负载均衡厂商将首先被 OSS 软件和云厂商取代。传统路由器/交换机供应商,例如 Arista/Cumulus/等。我认为在本地部署方面有更大的发展空间,但最终也会被公共云供应商及其本土物理网络所取代。

总的来说,我认为这是计算机网络的一个迷人时期!大多数系统向 OSS 和软件的转变正在将迭代速度提高几个数量级。此外,随着分布式系统通过“无服务器”范式继续向动态发展,底层网络和负载平衡系统的复杂性将需要相应增加。

相关推荐

Python自动化脚本应用与示例(python自动化脚本教程)

Python是编写自动化脚本的绝佳选择,因其语法简洁、库丰富且跨平台兼容性强。以下是Python自动化脚本的常见应用场景及示例,帮助你快速上手:一、常见自动化场景文件与目录操作O批量重命名文件...

如何使用Python实现一个APP(如何用python做一个程序)

要使用Python实现一个APP,你可以选择使用一些流行的移动应用开发框架,如Kivy、PyQt或Tkinter。这里以Kivy为例,它是一个跨平台的Python框架,可以用于创建漂亮的图形用户界面(...

免费定时运行Python程序并存储输出文档的服务推荐

免费定时运行Python程序并存储输出文档的服务推荐以下是几种可以免费定时运行Python程序并存储输出结果的云服务方案:1.PythonAnywhere特点:提供免费的Python托管环境支持定时...

【Python程序开发系列】如何让python脚本一直在后台保持运行

这是我的第385篇原创文章。一、引言让Python脚本在后台持续运行,有几种常见的方式,具体方式可以根据你的系统环境和需求选择。二、Linux或macOS系统2.1使用nohup命令no...

运行和执行Python程序(运行python的程序)

一、Python是一种解释型的脚本编程语言,这样的编程语言一般支持两种代码运行方式:交互式编程在命令行窗口中直接输入代码,按下回车键就可以运行代码,并立即看到输出结果;执行完一行代码,你还可以继续...

Python 初学者指南:计算程序的运行时长

在编写Python程序时,了解程序的运行时长是一项很有用的技能。这不仅能帮助你评估代码的效率,还能在优化程序性能时提供关键的数据支持。对于初学者来说,计算程序运行时长其实并不复杂,接下来就让我们看...

pyest+appium实现APP自动化测试,思路全总结在这里

每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试码同学抖音号:小码哥聊软件测试01appium环境搭建安装nodejshttp://nodej...

血脉觉醒后,编程小白我是如何通过Deepseek和Trae轻松开发软件的

以下就是作为一个编程小白的我,是如何一步步开发软件的保姆级教程,请点赞收藏:第一步:打开#deepseek#(首先关闭深度思考和联网搜索)输入或复制你要让它做一个什么样软件的要求和提示词(你可以先用...

我用Deepseek+Trae写的python小软件,小白也能轻松用上模型啦!

利用AI大模型deepseek,搭配TraeCN,用半个小时做了一个本地Ollama安装部署和一键卸载的小工具,哈哈哈!感觉还不错#deepseek#一直想做一个本地Ollama安装部署和一键卸载...

在安卓设备上运行Python的方法(安卓能运行python吗)

技术背景在安卓设备上运行Python可以为开发者提供更多的开发选择和灵活性,能够利用Python丰富的库和简洁的语法来开发各种应用,如游戏、脚本工具等。然而,由于安卓系统原生不支持Python,需要借...

零基础小白,DeepSeek全自动编程,超详细提示词,一键生成软件!

我前面发表了文章,详细说了编程零基础小白,如何利用DeepSeek进行编程的全过程,感兴趣的可以去看看:DeepSeek全自动编程很多人不会写提示词,不知道怎么开始对话。话不多说,请先看下图中的对话,...

小白用DeepSeek+Python编写软件(用python制作软件)

周末无事,用DeepSeek生成全部代码,写了一个mp3音乐播放器,几分钟搞定,DeepSeek确实太强大了。我的提示语是这么写的:“请用Python语言写一个音乐播放器,支持常见音乐格式,我是Pyt...

零基础使用DeepSeek开发Windows应用程序,超简单超实用!

你敢相信,我居然用DeepSeek开发了一个能用的Windows软件!整个过程就像和学霸同桌组队做作业,我负责提需求,DeepSeek负责写代码改bug,全程碰到任何问题直接丢给DeepSeek即可。...

第二篇:如何安装Python并运行你的第一个程序

欢迎回到我的Python入门教程系列!在上一篇中,我们讨论了为什么Python是一门值得学习的编程语言。今天,我们将迈出第一步:安装Python并运行你的第一个程序。无论你是Windows、macOS...

Python 运行,带你找入口,快速读懂程序

有C或Java编程开发经验的软件开发者,初次接触python程序,当你想快速读懂python项目工程时,是否觉得python程序有些太过随意,让你看有些无所适从,进而有些茫然。这是...

取消回复欢迎 发表评论: