负载均衡详解

一、 负载均衡详细介绍

1.1 四层负载均衡技术

1.1.1 经典四层负载均衡器 LVS 的相关术语

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS核心术语详解                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  【VIP - Virtual IP】                                           │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  负载均衡器对外提供服务的虚拟IP地址                      │   │
│  │                                                         │   │
│  │  示例:                                                  │   │
│  │  1.2.3.4:80 → 承载网站www.example.com的访问            │   │
│  │  1.2.3.4:443 → 承载HTTPS网站访问                        │   │
│  │                                                         │   │
│  │  特点:                                                  │   │
│  │  • 客户端直接访问的地址                                 │   │
│  │  • 通常是公网IP                                         │   │
│  │  • 可以在多个Director间漂移(高可用)                   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【DIP - Director IP】                                         │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  Director(负载均衡器)自身的IP地址                      │   │
│  │                                                         │   │
│  │  示例:                                                  │   │
│  │  10.0.1.10 → Director服务器的管理IP                     │   │
│  │                                                         │   │
│  │  用途:                                                  │   │
│  │  • 与后端RS通信的源地址(NAT模式)                     │   │
│  │  • 与上游设备通信的地址                                 │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【RIP - Real Server IP】                                       │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  后端真实服务器的IP地址                                  │   │
│  │                                                         │   │
│  │  示例:                                                  │   │
│  │  192.168.1.101 → 后端服务器1                            │   │
│  │  192.168.1.102 → 后端服务器2                            │   │
│  │  192.168.1.103 → 后端服务器3                            │   │
│  │                                                         │   │
│  │  特点:                                                  │   │
│  │  • 通常是私网IP                                         │   │
│  │  • 对客户端不可见                                       │   │
│  │  • 处理实际业务请求                                     │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【CIP - Client IP】                                            │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  发起请求的客户端的真实IP地址                           │   │
│  │                                                         │   │
│  │  重要性:                                                │   │
│  │  • 后端应用需要获取真实客户端IP                        │   │
│  │  • 日志记录、统计分析、安全防护需要                    │   │
│  │  • 通过X-Forwarded-For或TOA获取                       │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【LIP - Local IP (FullNAT专用)】                               │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  FullNAT模式下的内网转换IP地址                          │   │
│  │                                                         │   │
│  │  示例:                                                  │   │
│  │  LIP池:192.168.100.200-192.168.100.250               │   │
│  │                                                         │   │
│  │  作用:                                                  │   │
│  │  • 替代CIP作为与RS通信的源地址                         │   │
│  │  • 解决NAT模式RS网关必须指向LB的问题                  │   │
│  │  • 支持跨网段部署                                       │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  地址关系图:                                                    │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   [客户端]                                              │   │
│  │      │                                                  │   │
│  │      │ CIP:54321 → VIP:80                            │   │
│  │      ↓                                                  │   │
│  │   [Director]                                           │   │
│  │      │                                                  │   │
│  │      │ DIP:Port → RIP:Port(转发时)                  │   │
│  │      ↓                                                  │   │
│  │   [Real Server]                                        │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.1.2 LVS 转发模式及配置实例

LVS 支持四种转发模式:DR、TUN、NAT、FullNAT。每种模式都有其独特的适用场景。

DR 模式(Direct Routing)
复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS-DR模式详解                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  工作原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   请求阶段:                                            │   │
│  │   Client → [CIP→VIP] → Director                        │   │
│  │            修改目标MAC → DIP MAC                        │   │
│  │            源IP/目标IP保持不变!                        │   │
│  │                      ↓                                 │   │
│  │                   [RS]                                  │   │
│  │                                                         │   │
│  │   响应阶段:                                            │   │
│  │                   [RS]                                  │   │
│  │                      ↑                                 │   │
│  │            [RIP→CIP] 直接发送                         │   │
│  │            完全绕过Director!                          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  特点:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  ✓ 性能最高(无NAT开销)                               │   │
│  │  ✓ 响应直接返回,不经过Director                        │   │
│  │  ✓ 适合大多数场景                                      │   │
│  │  ✗ RS必须与Director同网段                              │   │
│  │  ✗ 需要ARP抑制配置                                      │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置实例:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # Director配置                                         │   │
│  │                                                         │   │
│  │  # 添加VIP                                              │   │
│  │  ifconfig eth0:0 1.2.3.4/24 up                        │   │
│  │                                                         │   │
│  │  # 添加虚拟服务(DR模式 -g)                            │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s rr -g                    │   │
│  │                                                         │   │
│  │  # 添加后端服务器                                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 192.168.1.101 -g         │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 192.168.1.102 -g         │   │
│  │                                                         │   │
│  │  # RS配置                                              │   │
│  │                                                         │   │
│  │  # 绑定VIP到lo接口                                      │   │
│  │  ifconfig lo:0 1.2.3.4/32 up                          │   │
│  │                                                         │   │
│  │  # ARP抑制配置                                          │   │
│  │  echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore       │   │
│  │  echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce    │   │
│  │  echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore      │   │
│  │  echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce    │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ARP抑制详解:                                                   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  arp_ignore参数:                                       │   │
│  │  • 0: 响应任何网卡的ARP请求(默认)                     │   │
│  │  • 1: 只响应本地接口上的ARP请求                         │   │
│  │  • 2: 只响应目标IP匹配本地接口的ARP请求                │   │
│  │                                                         │   │
│  │  arp_announce参数:                                    │   │
│  │  • 0: 使用任何接口的IP发送ARP(默认,可能暴露VIP)     │   │
│  │  • 1: 尽量使用与目标IP同网段的接口发送                  │   │
│  │  • 2: 只使用与目标IP精确匹配的接口发送                 │   │
│  │                                                         │   │
│  │  推荐配置(RS上):                                     │   │
│  │  arp_ignore = 1                                        │   │
│  │  arp_announce = 2                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
LVS-DR模式通过让Director仅修改数据包的目标MAC地址(保持IP不变)将请求转发给后端,而后端服务器必须将VIP绑定在回环接口(lo)上,这是因为物理网卡通常只能接收目标IP为自身真实IP的数据包,绑定lo相当于给内核协议栈开了一个"后门",让它能识别并接收目标为VIP的数据包,同时配合ARP抑制机制隐藏自身的VIP身份,确保请求只进不出;最终,后端服务器利用这个lo接口上的VIP作为源地址,将响应数据直接返回给客户端,完全绕过Director,从而实现了极高的吞吐量。
TUN 模式(IP Tunneling)
复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS-TUN模式详解                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  工作原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   请求阶段:                                            │   │
│  │                                                         │   │
│  │   Client → [内层: CIP→VIP]                             │   │
│  │            [外层: DIP→RIP] IPIP封装                    │   │
│  │                      ↓                                 │   │
│  │                   [RS]                                 │   │
│  │                                                         │   │
│  │   RS内核自动解封装                                      │   │
│  │   处理原始[CIP→VIP]请求                                │   │
│  │                                                         │   │
│  │   响应阶段:                                            │   │
│  │   [VIP→CIP] 直接发送 → Client                         │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  特点:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  ✓ 支持跨网段部署(可跨越不同机房)                     │   │
│  │  ✓ 性能较高                                            │   │
│  │  ✓ 响应直接返回                                        │   │
│  │  ✗ RS内核需要支持IPIP隧道                              │   │
│  │  ✗ 配置相对复杂                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置实例:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # Director配置                                         │   │
│  │                                                         │   │
│  │  # 加载ip_vs_ipip模块                                  │   │
│  │  modprobe ip_vs_ipip                                  │   │
│  │                                                         │   │
│  │  # 添加VIP                                              │   │
│  │  ifconfig tunl0 1.2.3.4/24 up                         │   │
│  │                                                         │   │
│  │  # 添加虚拟服务(TUN模式 -i)                           │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s rr -i                   │   │
│  │                                                         │   │
│  │  # 添加后端服务器                                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 172.16.1.101 -i         │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 172.16.1.102 -i         │   │
│  │                                                         │   │
│  │  # RS配置                                              │   │
│  │                                                         │   │
│  │  # 绑定VIP到tunnel接口                                 │   │
│  │  ifconfig tunl0 1.2.3.4/24 up                         │   │
│  │                                                         │   │
│  │  # ARP抑制(同DR模式)                                  │   │
│  │  echo 1 > /proc/sys/net/ipv4/conf/tunl0/arp_ignore   │   │
│  │  echo 2 > /proc/sys/net/ipv4/conf/tunl0/arp_announce │   │
│  │                                                         │   │
│  │  # 关闭隧道端口转发                                    │   │
│  │  echo 1 > /proc/sys/net/ipv4/conf/tunl0/disable_policy │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

在LVS的TUN模式下,整个数据流转过程就像是一场精密的"套娃"接力赛。当客户端的请求到达Director(负载均衡器)后,内核中的IPVS模块首先会像门卫一样拦截并检查数据包的目标IP和端口,确认它是否属于预先配置好的集群服务,只有验证通过,Director才会启动转发逻辑;紧接着,Director并不会像NAT模式那样修改原始数据,而是采用IP隧道技术,在原始数据包(源CIP -> 目标VIP)的外面,再封装一层新的IP头(源DIP -> 目标RIP),这就像把一封写好的信(原始包)装进了一个新的快递箱(外层IP)里,快递箱上只写着从Director到后端服务器(RS)的地址,中间的路由器只看外层快递箱的地址(RIP)进行投递,完全看不到里面的信件内容(VIP),从而实现了跨越不同网段的传输;当后端服务器(RS)收到这个包后,网卡发现协议类型是IPIP(隧道协议),于是内核自动进行解封装,拆掉外层快递箱,露出了里面的原始信件;此时,内核检查原始信件的目标地址是VIP,为了接收这个包,RS必须在Loopback(lo)接口上绑定这个VIP(这与DR模式原理一致,为了不占用物理网卡IP且避免ARP冲突),一旦内核发现lo接口上有这个VIP,就会接收并处理该请求;处理完毕后,RS构建响应包,源IP是VIP(假装自己是Director),目标IP是CIP(客户端),然后直接通过eth0物理网卡发送给客户端,完全绕过了Director,从而实现了高性能的负载均衡。

NAT 模式
复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS-NAT模式详解                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  工作原理:
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   请求阶段(Inbound):                                 │   │
│  │   Client → Director → RS                               │   │
│  │                                                         │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  源IP: CIP (不变)                               │   │   │
│  │   │  目标IP: VIP → RIP (仅修改目标IP)              │   │   │
│  │   │  源MAC: Client MAC → Director MAC               │   │   │
│  │   │  目标MAC: Director MAC → RS MAC                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   关键点:RS的网关必须指向Director!                   │   │
│  │                                                         │   │
│  │   响应阶段(Outbound):                               │   │
│  │   RS → Director → Client                              │   │
│  │                                                         │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  因为RS的网关是Director                          │   │   │
│  │   │  RS的响应包会自动路由回Director                  │   │   │
│  │   │  源IP: RIP → VIP (修改源IP!)                  │   │   │
│  │   │  目标IP: DIP → CIP (恢复客户端IP)              │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│  特点:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  ✓ 配置简单,易于理解                                   │   │
│  │  ✓ 支持端口映射                                        │   │
│  │  ✓ RS无需特殊配置                                      │   │
│  │  ✗ Director性能开销大(双向NAT)                       │   │
│  │  ✗ RS网关必须指向Director                              │   │
│  │  ✗ 扩展性受限                                          │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置实例:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # Director配置                                         │   │
│  │                                                         │   │
│  │  # 开启IP转发                                           │   │
│  │  echo 1 > /proc/sys/net/ipv4/ip_forward               │   │
│  │                                                         │   │
│  │  # 添加VIP(公网网卡)                                  │   │
│  │  ifconfig eth0:0 1.2.3.4/24 up                        │   │
│  │                                                         │   │
│  │  # 添加虚拟服务(NAT模式 -m)                          │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s rr -m                   │   │
│  │                                                         │   │
│  │  # 添加后端服务器                                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 192.168.1.101 -m        │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 192.168.1.102 -m        │   │
│  │                                                         │   │
│  │  # RS配置(网关指向Director)                          │   │
│  │  route add default gw 192.168.1.10                   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
LVS的NAT模式就像一个"全权代理的中转站",请求和响应都必须经过负载均衡器。当客户端请求到达时,负载均衡器将数据包的目标IP从虚拟IP(VIP)修改为后端真实服务器的IP(RIP)并转发;关键在于,为了让处理完的响应能回到负载均衡器,后端服务器的默认网关必须配置为负载均衡器的内网IP(DIP),这样响应包才会发回给负载均衡器,由它把源IP改回VIP后,最终返回给客户端。
FullNAT 模式(全地址转换)

FullNAT 模式是阿里巴巴开源的 LVS 增强版本,通过引入 LIP(Local IP)实现了完全透明的代理,彻底解耦了 Director 与后端 RS 的网络拓扑关系。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS-FullNAT模式详解                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  工作原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   核心创新:引入LIP(Local IP)                         │   │
│  │                                                         │   │
│  │   请求阶段:                                            │   │
│  │   Client → [CIP→VIP] → Director                        │   │
│  │            SNAT: CIP→LIP(源地址转换)                  │   │
│  │            DNAT: VIP→RIP(目标地址转换)                │   │
│  │                      ↓                                  │   │
│  │                   [RS]                                  │   │
│  │            RS看到: LIP→RIP的请求                       │   │
│  │                                                         │   │
│  │   响应阶段:                                            │   │
│  │                   [RS]                                  │   │
│  │                      ↑                                  │   │
│  │            源: RIP → 目标: LIP                         │   │
│  │            RS响应给LIP(Director的地址)                │   │
│  │            Director收到后再次转换:                       │   │
│  │            SNAT: RIP→VIP                               │   │
│  │            DNAT: LIP→CIP                              │   │
│  │            → Client                                    │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  与NAT模式的区别:                                              │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   NAT模式:                                              │   │
│  │   • 源地址被改为DIP(Director自己的IP)                │   │
│  │   • DIP通常是公网IP,数量有限                          │   │
│  │   • RS网关必须指向Director                              │   │
│  │                                                         │   │
│  │   FullNAT模式:                                          │   │
│  │   • 源地址被改为LIP(DIP的扩展/补充)                  │   │
│  │   • LIP可以是私网IP池,灵活扩展                        │   │
│  │   • RS网关指向自己的网段网关,无需指向Director          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  LIP的作用与价值:                                              │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   为什么要用LIP而不是直接用DIP?                        │   │
│  │                                                         │   │
│  │   场景:Director有1个DIP,但需要连接10000个后端RS     │   │
│  │                                                         │   │
│  │   NAT模式问题:                                         │   │
│  │   • 1个DIP的端口范围是0-65535                         │   │
│  │   • 如果每RS占用1个端口,最多服务65535个RS            │   │
│  │   • 实际上还有端口复用限制,更少                        │   │
│  │                                                         │   │
│  │   FullNAT + LIP解决方案:                               │   │
│  │   • LIP是一个IP池(如192.168.100.200-250,共51个)     │   │
│  │   • 每个LIP仍可服务65535个连接                        │   │
│  │   • 51个LIP × 65535 ≈ 330万连接                       │   │
│  │   • 轻松支持大规模RS集群                              │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  跨网段部署的奥秘:                                              │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   FullNAT能跨网段部署的关键:                           │   │
│  │                                                         │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │                                                 │   │   │
│  │   │     LIP网段 ←──三层路由可达──→ RIP网段         │   │   │
│  │   │   192.168.100.x          172.16.1.x             │   │   │
│  │   │                                                 │   │   │
│  │   │     只要路由器知道如何路由                        │   │   │
│  │   │     LIP和RIP就能通信                            │   │   │
│  │   │                                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   实际部署场景:                                        │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  场景1:同机房不同网段                           │   │   │
│  │   │  • LIP: 192.168.100.200                        │   │   │
│  │   │  • RIP: 192.168.101.101                        │   │   │
│  │   │  • 通过核心交换机三层互联                        │   │   │
│  │   ├─────────────────────────────────────────────────┤   │   │
│  │   │  场景2:跨机房部署(北京→上海)                  │   │   │
│  │   │  • LIP: 192.168.100.200                        │   │   │
│  │   │  • RIP: 172.16.101.101                         │   │   │
│  │   │  • 通过专线/VPN跨地域互联                        │   │   │
│  │   ├─────────────────────────────────────────────────┤   │   │
│  │   │  场景3:云环境部署                               │   │   │
│  │   │  • LIP: VPC内网IP                               │   │   │
│  │   │  • RIP: 其他可用区IP                             │   │   │
│  │   │  • 通过云厂商内网路由                             │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  特点:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  ✓ 支持真正的跨网段、跨机房部署                        │   │
│  │  ✓ RS网关无需指向Director                              │   │
│  │  ✓ Director和RS网络拓扑解耦                           │   │
│  │  ✓ 支持大规模RS集群                                    │   │
│  │  ✓ 适合云环境和混合云部署                              │   │
│  │  ✗ 需要LVS内核模块支持(aliyun/alibaba分支)           │   │
│  │  ✗ 配置相对复杂                                        │   │
│  │  ✗ 性能略低于DR模式(双重地址转换)                   │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置实例:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # Director配置                                         │   │
│  │                                                         │   │
│  │  # 加载FullNAT模块(需要aliyun/alibaba内核)           │   │
│  │  modprobe ip_vs_fullnat                                │   │
│  │                                                         │   │
│  │  # 开启IP转发                                           │   │
│  │  echo 1 > /proc/sys/net/ipv4/ip_forward              │   │
│  │                                                         │   │
│  │  # 添加VIP                                              │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s rr -b                  │   │
│  │  # 注意:-b 参数启用FullNAT模式                       │   │
│  │                                                         │   │
│  │  # 添加LIP池(内网IP池)                               │   │
│  │  ipvsadm --start-daemon master -t 1.2.3.4:80 \      │   │
│  │      --localip 192.168.100.200-192.168.100.250      │   │
│  │                                                         │   │
│  │  # 添加后端服务器                                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 172.16.1.101 -b       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 172.16.1.102 -b       │   │
│  │                                                         │   │
│  │  # RS配置(网关指向本机网段网关)                      │   │
│  │  route add default gw 172.16.1.1                      │   │
│  │  # 注意:不再是Director的IP!                          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │

└─────────────────────────────────────────────────────────────────┘

FullNAT 模式通过引入内网 IP(LIP),让负载均衡器(Director)在客户端和后端服务器(RS)之间扮演了一个完全透明的"全能代理人"。当客户端的请求到达 Director 的公网 VIP 时,Director 会立即执行"双重变脸":它不仅将目标地址从 VIP 修改为后端服务器的真实 IP(RIP),还会将源地址从客户端 IP(CIP)修改为自己的内网 IP(LIP),然后把这个"伪装"后的数据包发往内网;此时,RS 看到的请求就像是 Director 自己发来的,于是它把响应包直接发回给 LIP,Director 收到后再把源地址改回 VIP、目标地址改回 CIP,最终返回给客户端。

1.1.3 不同协议下的负载均衡

LVS 不仅支持常见的 HTTP 协议,还能处理 TCP、UDP 等多种协议的负载均衡:

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS协议支持                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  【TCP协议】                                            │   │
│  │                                                         │   │
│  │  典型场景:                                             │   │
│  │  • HTTP/HTTPS                                          │   │
│  │  • SSH/Telnet                                         │   │
│  │  • FTP/SFTP                                           │   │
│  │  • SMTP/POP3/IMAP                                     │   │
│  │  • 数据库连接(MySQL/PostgreSQL)                     │   │
│  │                                                         │   │
│  │  配置示例:                                             │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s rr                       │   │
│  │  ipvsadm -A -t 1.2.3.4:443 -s wlc                    │   │
│  │  ipvsadm -A -t 1.2.3.4:3306 -s sh                   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  【UDP协议】                                            │   │
│  │                                                         │   │
│  │  典型场景:                                             │   │
│  │  • DNS                                                │   │
│  │  • DHCP                                               │   │
│  │  • VoIP/SIP                                           │   │
│  │  • 游戏服务器                                          │   │
│  │  • 流媒体                                              │   │
│  │                                                         │   │
│  │  配置示例:                                             │   │
│  │  ipvsadm -A -u 1.2.3.4:53 -s rr                       │   │
│  │  ipvsadm -A -u 1.2.3.4:5060 -s lc                    │   │
│  │                                                         │   │
│  │  注意:UDP无连接概念,使用统一调度                     │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  【防火墙实例(FW)】                                    │   │
│  │                                                         │   │
│  │  两臂模式,实现双向负载均衡:                           │   │
│  │                                                         │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │                                                 │   │   │
│  │  │   Client        Director        RS              │   │   │
│  │  │     │              │              │              │   │   │
│  │  │     │──CIP→VIP───→│              │              │   │   │
│  │  │     │              │──DIP→RIP────→│              │   │   │
│  │  │     │              │              │──RIP→DIP───→│   │   │
│  │  │     │←────VIP→CIP──│              │              │   │   │
│  │  │                                                 │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │  配置:                                                  │   │
│  │  ipvsadm -A -f 1 -s rr                                 │   │
│  │  ipvsadm -a -f 1 -r RIP1 -g                           │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.1.4 获取真实的客户端 IP 地址和端口信息

在后端服务器获取真实客户端 IP 是一个常见且重要的需求。

场景分析
复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    获取真实客户端IP的需求                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  问题:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  在NAT模式下:                                          │   │
│  │  • RS看到的源IP是DIP/LIP,而非CIP                      │   │
│  │  • 应用日志记录的是错误的IP                            │   │
│  │                                                         │   │
│  │  在DR/TUN模式下:                                       │   │
│  │  • RS可以直接看到CIP                                   │   │
│  │  • 但某些情况下仍需特殊处理                            │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  解决方案:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  方案一:X-Forwarded-For头(Nginx/七层代理)             │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  X-Forwarded-For: CIP, CIP2, CIP3               │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │  方案二:TOA(TCP Option Address)                      │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  在TCP选项中携带CIP信息                          │   │   │
│  │  │  四层负载均衡时保留客户端信息                    │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │  方案三:Proxy Protocol                                 │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  HAProxy协议,在连接前发送代理信息头             │   │   │
│  │  │  PROXY TCP4 CIP DIP LPORT RPORT\r\n             │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
各模式下的实现方法
复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    各模式获取真实IP方案                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  【NAT模式】                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  L4 LB使用LIP替代CIP,RS无法直接获取                    │   │
│  │                                                         │   │
│  │  解决方案:                                             │   │
│  │  1. L4 LB在TCP选项中携带CIP(需要LB和RS都支持TOA)     │   │
│  │  2. L4 LB → L7代理 → RS(通过X-Forwarded-For)        │   │
│  │                                                         │   │
│  │  TOA配置示例:                                          │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  # L4 LB加载TOA模块                              │   │   │
│  │  │  modprobe toa                                  │   │   │
│  │  │                                                 │   │   │
│  │  │  # RS加载TOA模块                                │   │   │
│  │  │  modprobe toa                                  │   │   │
│  │  │                                                 │   │   │
│  │  │  # 应用读取CIP                                  │   │   │
│  │  │  getsockopt(sock, SOL_IP, TCP_TOA, &toa_opt)   │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【DR/TUN模式】                                                   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  RS可以直接看到CIP,无需特殊处理                        │   │
│  │  响应也直接从RS返回,不经过LB                           │   │
│  │                                                         │   │
│  │  注意:                                                  │   │
│  │  • 如果中间有NAT设备,需要额外处理                      │   │
│  │  • 应用直接读取连接对端地址即可                        │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【L7代理模式(推荐)】                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  L4 LB → Nginx → RS                                    │   │
│  │                                                         │   │
│  │  Nginx添加:                                            │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  proxy_set_header X-Real-IP $remote_addr;       │   │   │
│  │  │  proxy_set_header X-Forwarded-For $proxy_add_x │   │   │
│  │  │                              _forwarded_for;    │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │  应用读取:                                              │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  // 从HTTP Header获取                           │   │   │
│  │  │  String realIP = request.getHeader("X-Real-IP"); │  │   │
│  │  │  // 或                                           │   │   │
│  │  │  String realIP = request.getHeader(             │   │   │
│  │  │              "X-Forwarded-For");                │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.2 七层负载均衡技术

1.2.1 经典七层负载均衡器 Nginx 的部署架构

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    Nginx负载均衡部署架构                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  典型部署架构:                                                  │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │              [用户请求]                                  │   │
│  │                   │                                      │   │
│  │                   ↓                                      │   │
│  │     ┌─────────────────────────────────────┐            │   │
│  │     │          Nginx集群(入口)           │            │   │
│  │     │                                     │            │   │
│  │     │   ┌─────────┐ ┌─────────┐ ┌─────────┐│            │   │
│  │     │   │ Nginx 1 │ │ Nginx 2 │ │ Nginx 3 ││  ...      │   │
│  │     │   └────┬────┘ └────┬────┘ └────┬────┘│            │   │
│  │     │        │           │           │     │            │   │
│  │     │        └───────────┴───────────┘     │            │   │
│  │     │                  │                    │            │   │
│  │     │         Keepalived + VIP             │            │   │
│  │     └──────────────────┬────────────────────┘            │   │
│  │                        │                                │   │
│  │                        ↓                                │   │
│  │     ┌─────────────────────────────────────┐            │   │
│  │     │         Nginx集群(内部)           │            │   │
│  │     │                                     │            │   │
│  │     │   ┌─────────┐ ┌─────────┐ ┌─────────┐│            │   │
│  │     │   │ 静态资源│ │ API代理 │ │ WebSocket││            │   │
│  │     │   └────┬────┘ └────┬────┘ └────┬────┘│            │   │
│  │     └────────┴───────────┴───────────┴────┘            │   │
│  │                        │                                │   │
│  │                        ↓                                │   │
│  │     ┌─────────────────────────────────────┐            │   │
│  │     │          后端服务集群               │            │   │
│  │     │                                     │            │   │
│  │     │   ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │            │   │
│  │     │   │ App1 │ │ App2 │ │ App3 │ │ App4 │ │  ...    │   │
│  │     │   └─────┘ └─────┘ └─────┘ └─────┘ │            │   │
│  │     └─────────────────────────────────────┘            │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Nginx配置示例:                                                │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  http {                                                 │   │
│  │      # 定义上游服务器组                                  │   │
│  │      upstream backend_servers {                        │   │
│  │          server 10.0.1.10:8080 weight=5;               │   │
│  │          server 10.0.1.11:8080 weight=3;               │   │
│  │          server 10.0.1.12:8080 backup;                 │   │
│  │                                                         │   │
│  │          keepalive 1000;                               │   │
│  │      }                                                  │   │
│  │                                                         │   │
│  │      server {                                           │   │
│  │          listen 80;                                     │   │
│  │          server_name www.example.com;                   │   │
│  │                                                         │   │
│  │          # 静态资源                                      │   │
│  │          location /static/ {                            │   │
│  │              alias /var/www/static/;                     │   │
│  │              expires 7d;                                │   │
│  │          }                                              │   │
│  │                                                         │   │
│  │          # API代理                                      │   │
│  │          location /api/ {                               │   │
│  │              proxy_pass http://backend_servers;         │   │
│  │              proxy_set_header Host $host;               │   │
│  │              proxy_set_header X-Real-IP $remote_addr;  │   │
│  │          }                                              │   │
│  │      }                                                  │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.2.2 Nginx 转发粒度控制

Nginx 支持多种粒度的转发控制,从连接级到请求级:

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    Nginx转发粒度控制                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  【连接级转发(upstream)】                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  upstream块级别的负载均衡:                             │   │
│  │                                                         │   │
│  │  upstream backend {                                     │   │
│  │      server 10.0.1.10:8080;                            │   │
│  │      server 10.0.1.11:8080;                            │   │
│  │      server 10.0.1.12:8080;                            │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  所有到/upstream的请求都会进行负载均衡                   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【location级转发】                                              │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  基于URL路径的精细路由:                                 │   │
│  │                                                         │   │
│  │  location /api/users/ {                                 │   │
│  │      proxy_pass http://user_servers;                   │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  location /api/orders/ {                               │   │
│  │      proxy_pass http://order_servers;                  │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  location /api/payments/ {                             │   │
│  │      proxy_pass http://payment_servers;                │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【Header级转发】                                                │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  基于请求头的智能路由:                                   │   │
│  │                                                         │   │
│  │  # 基于版本header路由                                    │   │
│  │  location /api/ {                                       │   │
│  │      if ($http_x_api_version = "v2") {                  │   │
│  │          proxy_pass http://backend_v2;                 │   │
│  │      }                                                  │   │
│  │      if ($http_x_api_version = "v3") {                  │   │
│  │          proxy_pass http://backend_v3;                 │   │
│  │      }                                                  │   │
│  │      proxy_pass http://backend_default;                │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  # 基于Cookie路由                                        │   │
│  │  location / {                                           │   │
│  │      if ($cookie_user_tier = "premium") {              │   │
│  │          proxy_pass http://premium_servers;           │   │
│  │      }                                                  │   │
│  │      proxy_pass http://standard_servers;               │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【动静分离】                                                    │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # 静态资源 - 直接服务或CDN                             │   │
│  │  location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff) ${ │   │
│  │      expires 30d;                                       │   │
│  │      add_header Cache-Control public;                   │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  # HTML页面                                             │   │
│  │  location ~* \.html$ {                                  │   │
│  │      proxy_pass http://backend_servers;                 │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  # API请求                                              │   │
│  │  location /api/ {                                       │   │
│  │      proxy_pass http://api_servers;                     │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.2.3 获取真实的客户端 IP 地址和端口信息

Nginx 通过特定 header 传递真实客户端信息:

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    Nginx传递客户端IP机制                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  【X-Real-IP】                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  配置:                                                  │   │
│  │  proxy_set_header X-Real-IP $remote_addr;               │   │
│  │                                                         │   │
│  │  传递内容:                                              │   │
│  │  X-Real-IP: 203.0.113.50(真实客户端IP)                │   │
│  │                                                         │   │
│  │  使用场景:                                              │   │
│  │  • 简单直接                                             │   │
│  │  • 只有一个代理层时                                     │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【X-Forwarded-For】                                            │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  配置:                                                  │   │
│  │  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; │   │
│  │                                                         │   │
│  │  传递内容:                                              │   │
│  │  X-Forwarded-For: 203.0.113.50, 198.51.100.178         │   │
│  │                           第一个IP           第二个IP   │   │
│  │                           (原始客户端)       (上一跳)   │   │
│  │                                                         │   │
│  │  解析方式:                                              │   │
│  │  ┌─────────────────────────────────────────────────┐   │   │
│  │  │  # 获取第一个IP(原始客户端)                    │   │   │
│  │  │  real_ip = xff.split(',')[0].strip()           │   │   │
│  │  └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  【X-Forwarded-Port / X-Forwarded-Proto】                       │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  配置:                                                  │   │
│  │  proxy_set_header X-Forwarded-Port $server_port;       │   │
│  │  proxy_set_header X-Forwarded-Proto $scheme;            │   │
│  │                                                         │   │
│  │  传递内容:                                              │   │
│  │  X-Forwarded-Port: 443                                  │   │
│  │  X-Forwarded-Proto: https                              │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  完整配置示例:                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  location / {                                           │   │
│  │      proxy_pass http://backend;                         │   │
│  │                                                         │   │
│  │      # 保留原始Host                                     │   │
│  │      proxy_set_header Host $host;                       │   │
│  │                                                         │   │
│  │      # 传递客户端IP                                     │   │
│  │      proxy_set_header X-Real-IP $remote_addr;          │   │
│  │      proxy_set_header X-Forwarded-For                   │   │
│  │                      $proxy_add_x_forwarded_for;        │   │
│  │                                                         │   │
│  │      # 传递协议和端口                                   │   │
│  │      proxy_set_header X-Forwarded-Proto $scheme;        │   │
│  │      proxy_set_header X-Forwarded-Port $server_port;   │   │
│  │                                                         │   │
│  │      # 传递连接信息                                     │   │
│  │      proxy_set_header Connection "";                    │   │
│  │                                                         │   │
│  │      # 超时配置                                         │   │
│  │      proxy_connect_timeout 60s;                         │   │
│  │      proxy_read_timeout 60s;                           │   │
│  │      proxy_send_timeout 60s;                           │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3 Real Server 调度算法

调度算法决定了如何将客户端请求分配到后端服务器,是负载均衡的核心。

1.3.1 轮询(RR)

轮询算法将请求依次分配给每个服务器,循环往复。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    轮询调度算法(RR)                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  算法原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   请求序列:  R1  R2  R3  R4  R5  R6  R7  R8            │   │
│  │                ↓   ↓   ↓   ↓   ↓   ↓   ↓   ↓         │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │                                                 │   │   │
│  │   │   RS1 → RS2 → RS3 → RS1 → RS2 → RS3 → RS1 →...│   │   │
│  │   │                                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   规则:第N个请求 → 第(N mod 3)个服务器                │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  适用场景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  • 服务器性能一致                                      │   │
│  │  • 无状态服务                                          │   │
│  │  • 简单高效                                            │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置:ipvsadm -A -t 1.2.3.4:80 -s rr                           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3.2 加权轮询(WRR)

加权轮询根据服务器权重比例分配请求。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    加权轮询调度算法(WRR)                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  算法原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   服务器权重:                                           │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  RS1: weight=5                                 │   │   │
│  │   │  RS2: weight=3                                 │   │   │
│  │   │  RS3: weight=2                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   分配模式:                                            │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  周期内共5+3+2=10个请求                          │   │   │
│  │   │                                                 │   │   │
│  │   │  RS1: 5次  ████████████████                    │   │   │
│  │   │  RS2: 3次  ████████████                        │   │   │
│  │   │  RS3: 2次  ████████                            │   │   │
│  │   │                                                 │   │   │
│  │   │  请求序列: R1 R2 R3 R4 R5 R6 R7 R8 R9 R10     │   │   │
│  │   │               ↓  ↓  ↓  ↓  ↓  ↓  ↓  ↓  ↓   ↓   │   │   │
│  │   │  RS1:     1    2    3    4    5                 │   │   │
│  │   │  RS2:         1         2         3              │   │   │
│  │   │  RS3:              1         2                  │   │   │
│  │   │                                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  适用场景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  • 服务器性能不一致(CPU/内存差异)                    │   │
│  │  • 需要灰度发布(低权重先验证)                        │   │
│  │  • 资源调配优化                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s wrr                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.10 -w 5          │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.11 -w 3          │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.12 -w 2          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3.3 最少连接调度(LC)

最少连接算法将请求分配给当前连接数最少的服务器。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    最少连接调度算法(LC)                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  算法原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   选择当前活动连接数最少的服务器:                       │   │
│  │                                                         │   │
│  │   当前连接状态:                                          │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  RS1: 50个活动连接                              │   │   │
│  │   │  RS2: 30个活动连接  ← 最少,选择!              │   │   │
│  │   │  RS3: 45个活动连接                              │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   第11个请求 → RS2                                     │   │
│  │                                                         │   │
│  │   更新后:                                               │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  RS1: 50个活动连接                              │   │   │
│  │   │  RS2: 31个活动连接  (+1)                        │   │   │
│  │   │  RS3: 45个活动连接                              │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  适用场景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  • 长连接服务(数据库、游戏服务器)                    │   │
│  │  • 请求处理时间差异大的服务                            │   │
│  │  • 会话保持需求                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  公式:选择活动连接数最少的服务器                                │
│                                                                 │
│  配置:ipvsadm -A -t 1.2.3.4:80 -s lc                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3.4 加权最少连接调度(WLC)

加权最少连接是最常用的调度算法,综合考虑权重和当前负载。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    加权最少连接调度算法(WLC)                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  算法原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   选择负载最轻的服务器:                                 │   │
│  │                                                         │   │
│  │   公式:                                                │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │                                                 │   │   │
│  │   │   负载值 = (活动连接数 × 256 + 非活动连接数)    │   │   │
│  │   │             ÷ 权重                              │   │   │
│  │   │                                                 │   │   │
│  │   │   选择负载值最低的服务器                         │   │   │
│  │   │                                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  计算示例:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   服务器状态:                                           │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  RS1: weight=5, 活跃=10, 非活跃=2               │   │   │
│  │   │  RS2: weight=3, 活跃=5,  非活跃=1               │   │   │
│  │   │  RS3: weight=2, 活跃=3,  非活跃=0               │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   计算负载值:                                           │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  RS1: (10×256 + 2) ÷ 5 = 512.4                 │   │   │
│  │   │  RS2: (5×256  + 1) ÷ 3 = 427.0  ← 最低,选择! │   │   │
│  │   │  RS3: (3×256  + 0) ÷ 2 = 384.0                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  │   虽然RS3非活跃连接最少,但综合考虑后RS2负载最轻         │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  适用场景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  • 通用场景首选                                        │   │
│  │  • 性能差异 + 动态负载                                 │   │
│  │  • 生产环境推荐                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s wlc                       │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.10 -w 5          │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.11 -w 3          │   │
│  │  ipvsadm -a -t 1.2.3.4:80 -r 10.0.1.12 -w 2          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3.5 一致性哈希(CONNHASH)

一致性哈希确保相同源 IP 或目标 IP 的请求始终路由到同一服务器。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    一致性哈希调度算法(CONNHASH)                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  算法原理:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   哈希环:                                              │   │
│  │                                                         │   │
│  │           0°                                          │   │
│  │           │                                           │   │
│  │           │    ┌─────┐                                │   │
│  │           │    │ RS1 │ ← 位置: hash(RS1)              │   │
│  │           │    └─────┘                                │   │
│  │           │                                           │   │
│  │    270° ──┼─── 180°                                   │   │
│  │           │                                           │   │
│  │           │    ┌─────┐                                │   │
│  │           │    │ RS2 │ ← 位置: hash(RS2)              │   │
│  │           │    └─────┘                                │   │
│  │           │                                           │   │
│  │           │    ┌─────┐                                │   │
│  │           │    │ RS3 │ ← 位置: hash(RS3)              │   │
│  │           │    └─────┘                                │   │
│  │           │                                           │   │
│  │           90°                                         │   │
│  │                                                         │   │
│  │   路由规则:                                            │   │
│  │   hash(客户端IP) → 顺时针找到第一个服务器              │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  会话保持原理:                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   客户端A: hash("203.0.113.50") → RS2                   │   │
│  │   客户端B: hash("198.51.100.100") → RS1                 │   │
│  │   客户端C: hash("192.0.2.1") → RS3                      │   │
│  │                                                         │   │
│  │   后续请求:                                             │   │
│  │   客户端A的任何请求 → 始终路由到RS2                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  适用场景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  • 需要会话保持的场景                                   │   │
│  │  • 缓存服务器(相同资源到同一缓存)                    │   │
│  │  • 有状态服务                                          │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  配置:                                                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  # 基于源IP哈希                                         │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s sh                        │   │
│  │                                                         │   │
│  │  # 基于目标IP哈希(适合缓存场景)                       │   │
│  │  ipvsadm -A -t 1.2.3.4:80 -s dh                        │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3.6 连接模板

连接模板用于优化 TCP 连接复用,减少后端压力。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    连接模板(Connection Template)              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  问题背景:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   传统模式:                                            │   │
│  │   每个HTTP请求创建一个新连接                            │   │
│  │                                                         │   │
│  │   Client ────→ L7 LB ────→ RS                         │   │
│  │     │                                                   │   │
│  │     │ HTTP请求1 → 建立连接 → 处理 → 关闭连接           │   │
│  │     │ HTTP请求2 → 建立连接 → 处理 → 关闭连接           │   │
│  │     │ HTTP请求3 → 建立连接 → 处理 → 关闭连接           │   │
│  │                                                         │   │
│  │   问题:连接建立/关闭开销大                            │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  连接模板解决方案:                                              │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   同一客户端的请求复用同一后端连接:                     │   │
│  │                                                         │   │
│  │   Client ────→ L7 LB ────→ RS                         │   │
│  │     │                                                   │   │
│  │     │ HTTP请求1 → 建立连接 ───────────────────────┐    │   │
│  │     │ HTTP请求2 → 复用连接 ───────────────────────→│    │   │
│  │     │ HTTP请求3 → 复用连接 ───────────────────────→│    │   │
│  │     │                    连接保持打开 ─────────────┘    │   │
│  │                                                         │   │
│  │   L7 LB维护:                                          │   │
│  │   ┌─────────────────────────────────────────────────┐   │   │
│  │   │  连接模板表:                                     │   │   │
│  │   │                                                 │   │   │
│  │   │  ClientIP:Port ↔ RS:Port ↔ 后端连接              │   │   │
│  │   │                                                 │   │   │
│  │   │  203.0.113.50:54321 ↔ RS1:8080 ↔ TCP连接1       │   │   │
│  │   │  198.51.100.100:54322 ↔ RS2:8080 ↔ TCP连接2    │   │   │
│  │   │                                                 │   │   │
│  │   └─────────────────────────────────────────────────┘   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Nginx连接复用配置:                                             │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  upstream backend {                                     │   │
│  │      server 10.0.1.10:8080;                            │   │
│  │                                                         │   │
│  │      # 启用连接复用                                     │   │
│  │      keepalive 100;                                    │   │
│  │      keepalive_requests 1000;                         │   │
│  │      keepalive_timeout 60s;                            │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  │  location / {                                           │   │
│  │      proxy_pass http://backend;                        │   │
│  │                                                         │   │
│  │      # 启用HTTP长连接                                   │   │
│  │      proxy_http_version 1.1;                           │   │
│  │      proxy_set_header Connection "";                    │   │
│  │  }                                                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  效果对比:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │   指标           传统模式        连接复用模式           │   │
│  │  ────────────────────────────────────────────────────── │   │
│  │   后端连接数      N个请求=N个    N个请求≈10-100个      │   │
│  │   TCP握手开销     N次           减少90%+              │   │
│  │   TIME_WAIT      大量           显著减少               │   │
│  │   吞吐量          基准           提升2-3倍              │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

连接池是一种通过复用已建立的TCP连接来优化网络通信性能的技术。在传统的HTTP短连接模式下,客户端每次发起请求都需要与服务器经历完整的TCP三次握手建立连接,传输数据后再通过四次挥手断开连接,这个过程会消耗大量的CPU资源、内存以及网络往返时间(RTT)。连接池的核心机制在于"借用与归还":当客户端第一次请求数据时,会建立一条TCP连接(即一个包含IP、端口和系统内核状态记录的"数据管道");数据传输完成后,该连接并不会立即关闭,而是被保留在池中以"空闲"状态待命;当后续有新的请求时,客户端直接从池中取出这条现成的连接复用,从而完全跳过了昂贵的三次握手过程。这种"一次握手,多次传输"的模式,极大地降低了服务器处理连接的开销和网络延迟,显著提升了高并发场景下的系统吞吐量。

1.4 LVS 与 DPVS 对比

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                    LVS vs DPVS 对比                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  LVS(Linux Virtual Server):                                   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  原理:内核模块 + Netfilter钩子                         │   │
│  │                                                         │   │
│  │  数据包路径:                                           │   │
│  │  网卡 → 内核协议栈 → IPVS处理 → 转发                   │   │
│  │                                                         │   │
│  │  优点:                                                  │   │
│  │  • 内核自带,无需额外安装                               │   │
│  │  • 配置简单                                             │   │
│  │  • 稳定可靠                                             │   │
│  │                                                         │   │
│  │  缺点:                                                  │   │
│  │  • 性能受限于内核协议栈                                 │   │
│  │  • 中断和上下文切换开销                                 │   │
│  │  • 扩展性有限                                           │   │
│  │                                                         │   │
│  │  性能:~100万新建连接/秒,~10Gbps                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  DPVS(DPDK-based LVS):                                       │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  原理:用户态 + DPDK + 轮询模式                         │   │
│  │                                                         │   │
│  │  数据包路径:                                           │   │
│  │  网卡DMA → 用户态内存 → 轻量协议栈 → 转发              │   │
│  │                                                         │   │
│  │  优点:                                                  │   │
│  │  • 绕过内核,极致性能                                   │   │
│  │  • 无中断开销                                          │   │
│  │  • 线性多核扩展                                        │   │
│  │                                                         │   │
│  │  缺点:                                                  │   │
│  │  • 部署复杂                                            │   │
│  │  • 需要DPDK支持                                        │   │
│  │  • 学习曲线陡峭                                        │   │
│  │                                                         │   │
│  │  性能:~1000万新建连接/秒,~100Gbps                    │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  选型建议:                                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  场景                    推荐方案                        │   │
│  │  ───────────────────────────────────────────────────────│   │
│  │  中小规模(<100万并发)   LVS                           │   │
│  │  大规模(100万-1000万)   DPVS                         │   │
│  │  超大规模(>1000万)       DPVS + 集群                  │   │
│  │  快速部署                 LVS                          │   │
│  │  极致性能                 DPVS                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

LVS(Linux Virtual Server)与IPVS的关系可以理解为"整体架构"与"核心引擎":LVS是由章文嵩博士开发的开源负载均衡解决方案,而IPVS(IP Virtual Server)是LVS在内核中实现的具体模块,负责执行核心的流量调度。其工作原理是从上至下的协同配合:用户空间的管理工具 ipvsadm 负责接收管理员的指令(如添加虚拟服务和后端服务器),并将这些规则配置到内核空间的IPVS模块中;当客户端的数据包到达服务器时,会进入内核网络协议栈,IPVS模块会在数据包的流向路径上(如PREROUTING和INPUT链)进行拦截。根据预设的规则和调度算法(如轮询、最小连接数等),IPVS会修改数据包的目的地------例如在DR模式下修改目标MAC地址,或在NAT模式下修改目标IP地址------然后将数据包转发给选定的后端真实服务器,从而实现高效的分发。DPVS 的原理可以看作是 LVS 的"完全体"进化,它利用 DPDK 技术实现了"内核旁路",不再依赖 Linux 内核协议栈,而是直接在用户态接管网卡硬件,通过轮询机制和零拷贝技术,像工厂流水线一样高速处理数据包,从而彻底消除了内核中断和上下文切换的开销;它与 LVS 的核心区别在于:LVS 是在内核里"搭便车",利用内核自带的钩子修改数据包,虽然比传统软件快,但仍受限于内核锁和协议栈的繁琐处理,而 DPVS 则是"自己修路",在用户态自建了一套轻量级协议栈,将网卡与 CPU 核心一对一绑定,虽然部署和维护门槛更高,但能轻松跑满万兆网卡,专为应对互联网大厂那种每秒百万级新建连接的极端流量场景而生。

0voice · GitHub

相关推荐
2401_8734794012 分钟前
固件升级如何按地区分批推送?IP地址查询定位决定升级策略
网络协议·tcp/ip·php
程序员老邢13 分钟前
【产品底稿 07】商助慧 Admin 运维模块落地:从 “能跑” 到 “能运维”,3 个页面搞定日常排障
java·运维·经验分享·spring boot·后端
net3m3321 分钟前
所有esp_websocket_client_send。。。的地方都加锁,就不容易websocket 断线重连
网络·websocket·网络协议
Jiangxl~34 分钟前
IP数据云如何为不同行业提供精准IP查询与风险防控解决方案?
网络·网络协议·tcp/ip·算法·ai·ip·安全架构
一口Linux40 分钟前
Linux C编程 | 从0实现telnet获取程序终端控制权
linux·运维·c语言
你觉得脆皮鸡好吃吗41 分钟前
HTTP (XSS前简单了解)
网络·网络协议·http·网络安全学习
willhuo1 小时前
Certbot工具在CentOS 7.9上申请和配置SSL证书完整教程
linux·centos·ssl
qq_411262421 小时前
四博 AI 智能音箱方案:基于 ESP32-S3 打造远场拾音、多网络接入、可二次开发的 AI 语音终端
网络·人工智能·智能音箱
QH139292318802 小时前
Rohde & Schwarz FSWX3044 FSWX3026信号与频谱分析仪
网络·功能测试·单元测试·集成测试·模块测试
zhangrelay2 小时前
三分钟云课实践速通--大学物理--python 版
linux·开发语言·python·学习·ubuntu·lubuntu