你真的了解 Load Balance 嘛

本文深入探讨了负载均衡(LB)的概念、硬件设备(如F5和Netscaler)的历史,以及软件如LVS和Nginx的角色。作者分享了构建LB的基本原理,涉及TCP/IP模型和调度算法,包括RR、WRR等,并针对复杂场景如高流量预热问题提供了解决方案。最后,文章涵盖了K8S中的LB选项和云服务商ELB的比较。

在计算中,Load Balance[1] 是指在一组资源(计算单元)上分配一组任务的过程,目的是使其整体处理更有效率。负载均衡可以优化响应时间,避免一些计算节点不均衡地超载,而其他计算节点则被闲置

同时,负载均衡, 反向代理, 网关 这些模块功能也比较相似,所以本文宽泛的将 LB 代指所有提供类似功能的开源软件以及设备

以下分享来自既做过专业运维又能卷Go和Rust编程的IT老炮董润泽,大家来看看他对LB的总结吧。

为什么需要 LB

能认识上图的人,都是 Old Gun 了。硬件负载均衡设备 F5Netscaler

上一代互联网基础架构,必不可少的接入层设备,当时 lvs 刚起步,fullnat 还没有流行起来。所以需要硬件设备做接入层 LB

在赶集网的时候,Netscaler 有两台设备,一主一备,后来设备到期,公司因为成本问题,没有购买后续维修服务,硬是撑到了和 58 合并

后来淘宝开源了 fullnat 模式的 lvs 代码,一般公司都是 lvs + nginx 实现接入层:对外 BGP IP, Lvs+OSPF 构建 tcp layer 4 接入层, nginx 负责 offload ssl 配置各种转发逻辑

宽泛来说,这里面 lvs, nginx 都是 Load Balance 软件,除了按照一定算法均衡 backend 设备的负载,LB 还要检测后端 Server 的存活状态,自动摘掉故障节点

基本常识

那么问题来了,如何构建 Load Balance 设备或是软件呢?本质还是理解 tcp/ip 模型及底层原理

如上图所示,物理层,Mac 层,IP 层,TCP 层, HTTP/HTTPS 等七层。每层都是有不同的 header, 然后封装好 data 后传递给下一层,发送数据与接收数据逻辑相反

不同的 LB 及模式工作在不同模型,比如我们常见的 Nginx 常工作在七层,在用户态解析 http/https 协议然后转发请求

LVS 很多种模式,工作在二,三,四层都可以

Linux Virtual Server

Linux Virtual Server (lvs) 是 Linux 内核自带的负载均衡器,也是目前性能最好的软件负载均衡器之一。lvs 包括 ipvs 内核模块和 ipvsadm 用户空间命令行工具两部分

在 lvs 中,节点分为 Director Server 和 Real Server 两个角色,其中 Director Server 是负载均衡器所在节点,而 Real Server 则是后端服务节点

当用户的请求到达 Director Server 时,内核 netfilter 机制的 PREROUTING 链会将发往本地 IP 的包转发给 INPUT 链(也就是 ipvs 的工作链,在 INPUT 链上,ipvs 根据用户定义的规则对数据包进行处理(如修改目的 IP 和端口等),并把新的包发送到 POSTROUTING 链,进而再转发给 Real Server

阿里开源 LVS 很久了,但是最新的 fullnat 代码一直没放出,七牛使用的 lvs 内核版本过低,只能用 linux 2.7 kernel, 连硬件支持都很差了。所以后面会讲到 dpvs[2]

Nat 是将修改数据包的目的 IP 和端口,将包转发给 RealServer (rs 不需要做任务设置), 此时 Director Server 即 LVS 是做为网关的,处于同一个局域网。包进来做 DNAT,出去做 SNAT

所有流量都经过 LVS, 很容易成为瓶颈。一般用于运维 OP 性质的多一些,服务正常业务流量有问题。

DR (Direct Route) 模式性能最好,工作在二层,通过修改数据包的 Mac 地址来实现转发,属于单臂 one-arm 模式,所以要求二层可达

进来的流量经过 LVS, 出去的直接返回给 client, 以前在赶集网时 MySQL 多用 DR 模式

这个模式需要修改 Real Server, 配置 arp_ignore 和 arp_announce 忽略对vip的ARP解析请求,同时 lo 添加对应的 VIP

Tunnel 是典型的隧道模式

Fullnat 解决了 Nat 的不足,机器可以无限扩展,当然也要受限于单机 lvs 的网卡及 cpu 性能

同时为了让服务获取 client 真实 IP, 需要加载 TOA 模块,将 IP 写到 tcp option 中

DPDK + LVS = DPVS

IQIYI 前几年开源了 DPVS, 主流公司都有自己的 DPDK LB 轮子,你不造一个都不好意思说是大公司

另外,阿里开源的 fullnat 模块还停留在 linux 2.6.32 kernel, 很多现代机器支持不好,而且 2021 年了,linux 主流内核都是 4.0 及以上

主要优化就是由 DPDK bypass 内核,完全用户态接管网卡,同时重写 tcp/ip 协议栈代码,这样避免了内核空间与用户空间的来回拷贝

上面是 dpvs 的整体架构,里面细节超多,感兴趣可以网上搜我的文章,以前写过一系列

性能 Benchmark 据说可以达到线速,公司用的话还得调研一下。开源产品宣传的很好,实际测起来数据可能不是那么回事,需要有专人调优

调度算法

  • Round-robin (ip_vs_rr.c)

  • Weighted round-robin (ip_vs_wrr.c)

  • Least-connection (ip_vs_lc.c)Weighted least-connection (ip_vs_wlc.c)

  • Locality-based least-connection (ip_vs_lblc.c)

  • Locality-based least-connection with replication (ip_vs_lblcr.c)

  • Destination hashing (ip_vs_dh.c)

  • Source hashing (ip_vs_sh.c)

  • Shortest expected delay (ip_vs_sed.c)

  • Never queue (ip_vs_nq.c)

  • Maglev hashing (ip_vs_mh.c)

上面是主流 LB 设备的调度算法,面试八股文必备,一般 RR 简单的轮询就够了。复杂一些的需要加个权,一般都是辗转相除实现的 GCD 最大公约数

这就够了嘛?其实不够的,比如我们线上遇到过预热的问题,服务流量特别大,新起来的机器 RR 过来的话瞬间 QPS 超高,影响服务性能,表现为 GC 特别频繁,同时请求的 latency 非常高

怎么解决呢?参考 Nginx 的 Smooth Weighted Round-Robin (SWRR) 平滑移动加权算法

云厂商的 LB

暂时只看 AWS Cloud, 一般我们都用 elb 做入口,涉及到 elb, alb, clb, nlb 概念巨多

大家可以参考官网看下区别,无外乎是否支持 layer 4、layer 7, 是否支持按 path 路由,还有一些高级功能等等的区别

具体实现,因为是黑盒,可能 c/c++ 自己写,也可能是 nginx 魔改,谁知道呢

K8S 的 LB

K8S 里面主要是三类:Service 四层,Ingress 七层,以及所谓的 Service Mesh 模式

Service 允许指定你所需要的 Service 类型,默认是 ClusterIP, 主要类型有:

ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。这也是默认的 ServiceType

NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到自动创建的 ClusterIP 服务。通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务

LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上

ExternalName:通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com), 无需创建任何类型代理

除了类型主要用三种工作模式:userspace proxy, iptables model, ipvs model. 现在性能最好默认的就是 ipvs 模式,如果机器不支持会 fallback 到 iptables

网上有性能对比,差距还是蛮明显的。Service 工作在四层,有些需求是按照 path 把请求转发到不同服务,这时就需要用到 Ingress

上图的 Ingress 由 nginx 实现,感兴趣的可以参考官网

对于流行的 Service Mesh, 每个 POD 都有 sidecar 容器来劫持流量,好处是业务无需配置服务发现,熔断,限流等等,这些都由 SM 的控制面来配

缺点是中间引入过多的 proxy, 服务可观测性是个挑战,A 调 B 服务慢了,中间有多个 sidecar, 扯皮就很难受了

小结

今天的分享就这些,写文章不容易,如果对大家有所帮助和启发,请大家帮忙点击再看点赞分享 三连

关于 Load Balance 大家有什么看法,或是文章有内容错误,欢迎留言一起讨论,大牛多留言 ^_^

参考资料

[1]

Load Balance From wikipedia: https://en.wikipedia.org/wiki/Load_balancing_(computing),

[2]

dpvs: https://github.com/iqiyi/dpvs,

<think>嗯,用户想了解负载均衡(LB)的工作原理及配置方法。首先,我需要回顾一下已有的引用内容,看看哪些信息可以直接用上。引用[1]提到Ribbon的负载均衡策略和轮询算法,引用[2]说明了LB集群的基本构成,引用[3]涉及Service如何转发流量到Pod,引用[4]列出了常用的调度算法,引用[5]详细解释了LVS-NAT的工作原理。这些内容应该能帮助构建回答的结构。 首先,负载均衡的核心原理是什么?根据引用[4]和[5],负载均衡主要是通过调度算法将流量分发到多个服务器,提升性能和可靠性。需要分步骤解释,可能包括流量分发、健康检查、会话保持等。 工作原理部分,可能需要分点说明,比如流量分发、调度算法、健康检查和会话保持。引用[5]中的LVS-NAT模式可以作为网络层负载均衡的例子,而应用层的可能需要引用[3]中的Service转发到Pod的情况。调度算法方面,引用[4]里的轮询、加权轮询、最少连接等需要详细说明,每个算法适合什么场景。 配置方法的话,可能需要分硬件和软件两种情况。硬件负载均衡器可能涉及配置虚拟服务器、算法选择、健康检查设置等。软件方面,比如Nginx的配置,引用[3]中的Service配置可能需要提到Kubernetes的YAML文件,Ribbon的配置可以参考引用[1]中的策略替换方法。 还要注意用户提到的配置步骤,比如硬件配置的步骤可能包括定义虚拟IP、选择算法、设置健康检查等。软件部分可能需要具体的配置示例,比如Nginx的upstream配置或者Kubernetes的Service定义。引用[1]中的Ribbon策略替换也是一个配置的例子,可以说明如何自定义负载均衡策略。 另外,用户可能想知道不同场景下如何选择负载均衡类型。比如,应用层负载均衡适合HTTP请求,而网络层适合TCP/UDP。引用[5]中的LVS-NAT属于网络层,而引用[3]中的Service可能属于应用层或传输层,需要区分清楚。 可能还需要提到健康检查的重要性,确保后端服务器的可用性,引用[2]中提到的LB节点可能涉及健康检查的配置。会话保持部分,可以通过Cookie或IP哈希来实现,引用[4]中的原地址散列可能属于会话保持的一种方式。 在回答时,要确保结构清晰,分工作原理和配置方法两部分。每个部分下再分小点,使用示例和引用支持。例如,在调度算法部分,引用[4]中的列表可以作为主要来源,并简要解释每个算法。配置方法中,引用[1]和[5]的例子能帮助说明软件和硬件的不同配置方式。 最后,生成相关问题需要考虑用户可能的后续疑问,比如如何选择调度算法、不同厂商的配置差异、性能优化等。确保问题覆盖原理、配置、优化和场景选择等方面。 检查是否需要更多的技术细节,比如具体配置文件的代码块,或者更详细的步骤说明。例如,Nginx的配置示例和Kubernetes的Service YAML示例,能帮助用户更直观地理解配置方法。同时,确保所有引用正确标注,比如LVS-NAT的原理来自引用[5],调度算法来自引用[4]等。 总结一下,回答的结构应该是先原理后配置,每个部分分点详细说明,结合引用中的具体信息,并给出配置示例和相关问题。确保语言简洁,技术术语准确,符合用户的需求。</think>### 负载均衡(LB)工作原理及配置方法 #### 一、负载均衡的核心原理 1. **流量分发** 负载均衡通过调度算法将用户请求分发到多个后端服务器,避免单点过载,提升系统吞吐量和容错能力。例如,轮询算法$Round\ Robin$会按顺序分配请求到服务器列表中的节点[^4]。 2. **调度算法** - **轮询(Round Robin)**:均等分配请求,适用于服务器性能相近的场景。 - **加权轮询(Weighted Round Robin)**:根据服务器权重分配流量,权重高的节点处理更多请求。 - **最少连接(Least Connection)**:优先将请求分发给当前连接数最少的服务器,适合长连接场景。 - **源地址散列(Source Hashing)**:根据用户IP或端口计算哈希值,固定分配到特定服务器,适用于会话保持需求。 3. **健康检查** 负载均衡器定期检测后端服务器的健康状态(如心跳检测),自动剔除故障节点,确保流量仅转发到可用服务器[^2]。 4. **网络层级差异** - **网络层(如LVS-NAT)**:通过修改数据包目标IP实现流量转发,适合处理TCP/UDP协议[^5]。 - **应用层(如Nginx)**:解析HTTP/HTTPS协议内容(如URL、Header),支持更精细的规则(如按路径分发)[^3]。 --- #### 二、配置方法 ##### 1. 硬件负载均衡器(以F5为例) - **步骤**: 1. 定义虚拟服务器(Virtual Server),指定对外服务的IP和端口。 2. 配置调度算法(如加权轮询)。 3. 添加后端服务器池(Pool)并设置健康检查策略(如HTTP状态码检测)。 4. 启用会话保持(如基于Cookie或源IP绑定)。 ##### 2. 软件负载均衡器 - **Nginx配置示例**: ```nginx http { upstream backend { server 192.168.1.1 weight=3; # 权重为3 server 192.168.1.2; least_conn; # 使用最少连接算法 } server { listen 80; location / { proxy_pass http://backend; } } } ``` - **Kubernetes Service配置**: ```yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 9376 type: LoadBalancer sessionAffinity: ClientIP # 基于客户端IP的会话保持 ``` - **Ribbon自定义策略(Java)**: 通过替换默认的`RoundRobinRule`,实现自定义负载均衡逻辑[^1]。 --- #### 三、场景选择建议 1. **高并发Web服务**:使用应用层负载均衡(如Nginx),结合最少连接算法。 2. **微服务架构**:采用客户端负载均衡(如Ribbon),减少中心节点压力。 3. **TCP长连接**:优先选择网络层方案(如LVS),提升转发效率[^5]。 --- §§ 相关问题 §§ 1. 如何根据业务需求选择合适的负载均衡算法? 2. 负载均衡器的健康检查机制有哪些常见类型? 3. 如何通过Kubernetes实现跨集群的负载均衡? 4. 负载均衡器在高并发场景下可能遇到哪些性能瓶颈?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值