LVS 负载均衡完全指南:从入门到精通

第一章:LVS 核心原理与架构

引言

在互联网飞速发展的今天,单台服务器早已无法承载海量用户的访问。负载均衡技术应运而生,它像交通指挥官一样,将流量智能地分发到多台服务器上,确保系统的高性能、高可用。

LVS(Linux Virtual Server)是 Linux 内核层面的高性能负载均衡解决方案,被广泛应用于淘宝、腾讯、百度等互联网巨头的生产环境。本章将深入讲解 LVS 的核心架构和工作原理。

1.1 负载均衡器的网络结构

负载均衡的三层架构

现代分布式系统通常采用三层负载均衡架构:

复制代码
用户请求
    ↓
[第一层:DNS 负载均衡]
    ↓
[第二层:LVS 四层负载均衡]
    ↓
[第三层:Nginx/HAProxy 七层负载均衡]
    ↓
[后端服务器集群]

第一层:DNS 负载均衡

  • 将域名解析到多个 LVS 节点的 VIP
  • 实现地理级别和机房级别的负载均衡
  • 配合 GSLB(全局服务器负载均衡)实现跨地域分发

第二层:LVS 四层负载均衡

  • 基于 IP 和端口进行流量分发
  • 性能极高,可处理百万级并发
  • 支持 DR、NAT、TUN、FullNAT 四种工作模式

第三层:七层负载均衡

  • 基于 HTTP 协议内容进行分发
  • 支持会话保持、URL 路由、SSL 卸载
  • 通常使用 Nginx、HAProxy 等软件
网络拓扑设计

单机房架构

复制代码
                    ┌─────────────┐
                    │   互联网    │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │  边界路由器  │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
         ┌────▼────┐  ┌────▼────┐  ┌────▼────┐
         │ LVS-1   │  │ LVS-2   │  │ LVS-3   │
         │(VIP:1.2.3.100)   │  │(VIP:1.2.3.100)   │
         └────┬────┘  └────┬────┘  └────┬────┘
              │            │            │
              └────────────┼────────────┘
                           │
              ┌────────────┴────────────┐
              │                         │
         ┌────▼────┐               ┌────▼────┐
         │ RS-1    │               │ RS-2    │
         │ 10.0.0.1│               │ 10.0.0.2│
         └─────────┘               └─────────┘

1.2 IPVS 深度解析

IPVS 模块化设计

IPVS (IP Virtual Server) 是 Linux 内核中实现负载均衡的核心模块。抛开那些复杂的代码逻辑,其核心设计思想可以概括为两件事:"IPVS 如何管理不同协议" 和 "如何处理复杂的连接(如 FTP)及连接保持"。

核心概念:像插座一样的插件系统

IPVS 采用模块化设计,就像一个插座系统:

  • IPVS 核心 :定义标准的 ip_vs_app 结构(相当于插座)
  • 协议模块:TCP、UDP、FTP 等作为独立插件(相当于插头)

当系统启动时,IPVS 先定义标准的 "插座",当你要注册一个协议时,系统会分配一个新 "插头" 并插到插座上。

设计优势

  1. 灵活性高:支持新协议无需改动核心代码,只需开发新插件
  2. 扩展性强:可以动态加载 / 卸载协议模块
  3. 维护性好:各协议模块独立,便于调试和优化
负载均衡调度机制

Hash 链表与调度算法

当数据包进入 IPVS 时,处理流程如下:

  1. 查找阶段:先检查 Hash 表,判断是否已有连接
  2. 调度阶段 :如果是新连接,调用 ip_vs_schedule 从后端服务器池选择最合适的机器

这个过程本质就是负载均衡的核心 ------"如何把请求均匀分发给后端服务器"。

调度算法详解

LVS 提供十多种调度算法,以下是核心算法的详细解析:

1. 轮询算法 (Round Robin, RR)

最简单直观的算法,按顺序依次分配请求。

复制代码
请求序列: 1  2  3  4  5  6  7  8  9  10...
服务器:   RS1→RS2→RS3→RS1→RS2→RS3→RS1→RS2→RS3→RS1...

优点 :实现简单,分配均匀缺点 :不考虑服务器负载差异适用场景:后端服务器性能相近的静态服务

2. 加权轮询算法 (Weighted Round Robin, WRR)

在轮询基础上引入权重概念,性能好的服务器分配更多请求。

复制代码
RS1 权重: 100
RS2 权重: 200
RS3 权重: 150

请求序列: RS1→RS2→RS2→RS3→RS2→RS1→RS2→RS2→RS3...

权重计算

复制代码
某个服务器分配次数 = (服务器权重 / 总权重) × 总请求数

优点 :考虑服务器性能差异缺点 :仍然不考虑实时负载适用场景:后端服务器配置不同的场景

3. 最小连接算法 (Least Connection, LC)

选择当前连接数最少的服务器。

复制代码
当前状态:
RS1: 1000 个连接
RS2: 800 个连接
RS3: 500 个连接

新请求 → 分配到 RS3(连接数最少)

优点 :考虑实时负载,适合长连接场景缺点 :可能出现 "抖动"(连接释放后突然又被分配)适用场景:数据库、长连接服务

4. 加权最小连接算法 (Weighted Least Connection, WLC)

结合连接数和权重,计算 "负载指数"。

复制代码
负载指数 = 当前连接数 / 服务器权重

RS1: 1000 连接 / 权重 100 = 10
RS2: 800 连接 / 权重 200 = 4
RS3: 500 连接 / 权重 150 = 3.33

新请求 → 分配到 RS3(负载指数最小)

优点 :综合考虑连接数和服务器性能适用场景:最通用的生产环境算法

5. 源地址哈希算法 (Source Hash, SH)

根据客户端源 IP 进行哈希,确保同一 IP 的请求总是分配到同一台服务器。

复制代码
Hash(IP) % 服务器数量 = 服务器索引

Hash(192.168.1.10) % 3 = 1 → RS2
Hash(192.168.1.11) % 3 = 0 → RS1

优点 :天然支持会话保持,无需额外配置缺点 :无法均匀分配流量,可能热点问题适用场景:需要会话保持但无法使用 Cookie 的场景

6. 一致性哈希算法 (Consistent Hash)

用于分布式缓存场景,服务器变化时最小化数据迁移。

复制代码
虚拟节点环:
RS1: [节点1, 节点2, 节点3]
RS2: [节点4, 节点5]
RS3: [节点6, 节点7, 节点8]

Hash(key) 顺时针找到第一个节点

优点 :服务器增删时影响最小适用场景 :缓存集群(Redis、Memcached)

FTP 协议特殊处理

为什么 FTP 如此特殊?

FTP 是 LVS 唯一特殊处理的协议,这是由 FTP 的工作方式决定的。

普通 TCP/UDP 协议

  • 就像寄信,IP 地址和端口写在信封上
  • LVS 只需修改信封(IP 头)就能转发

FTP 协议的特殊性

  • 传输数据时,在数据包 ** 内容(Payload)** 里也写上 IP 地址和端口
  • LVS 改了信封,但信纸里的 IP 没改

问题场景

主动模式 FTP 连接流程:

复制代码
1. 客户端 (192.168.1.100) 连接服务器 21 端口(控制连接)
2. 客户端发送 PORT 命令:PORT 192,168,1,100,48,97
   → 表示:我会在 192.168.1.100:12481 端口等待数据连接
3. 服务器尝试连接 192.168.1.100:12481
   → 失败!因为这是内网 IP,服务器无法连接

LVS 的解决方案

IPVS 专门编写 FTP 插件,负责:

  1. 检测 FTP 协议(主动 / 被动模式)
  2. 提取 Payload 中的 IP 地址和端口
  3. 将内网 IP 替换为 LVS 的外网 IP
  4. 重新计算 TCP 校验和

处理流程

复制代码
客户端 PORT 命令: PORT 192,168,1,100,48,97
    ↓
LVS FTP 模块检测到 FTP
    ↓
提取 IP: 192.168.1.100, Port: 12481
    ↓
替换为: PORT 1,2,3,100,48,97 (1.2.3.100 是 LVS 的外网 IP)
    ↓
重新计算校验和
    ↓
转发修改后的包

被动模式处理

被动模式也需要特殊处理,因为服务器返回的 PASV 响应中也包含 IP 和端口。

复制代码
服务器 PASV 响应: 227 Entering Passive Mode (192,168,1,200,19,136)
    ↓
LVS FTP 模块检测
    ↓
替换 IP: 1.2.3.100
    ↓
转发: 227 Entering Passive Mode (1,2,3,100,19,136)

配置 FTP 支持

复制代码
# 加载 FTP 模块
modprobe ip_vs_ftp

# 在后端服务器上也加载(用于被动模式)
modprobe nf_conntrack_ftp

# 验证模块加载
lsmod | grep ftp

为什么只支持 FTP?

因为 FTP 是唯一在数据包 Payload 中包含 IP 地址的常见协议。其他协议(HTTP、SMTP 等)都在头部或应用层协议中传输地址信息,不需要修改 Payload。


第二章:基础功能与实战

2.1 提供外网 VIP 和流量均衡

外网 VIP 架构设计

网络拓扑

复制代码
互联网用户
    ↓ DNS 解析: www.example.com → 1.2.3.100
    ↓
[边界路由器]
    ↓
[LVS 集群] - VIP: 1.2.3.100
    ├─ LVS-1 (主) - 10.0.1.10
    ├─ LVS-2 (备) - 10.0.1.11
    └─ LVS-3 (备) - 10.0.1.12
    ↓
[后端服务器集群]
    ├─ RS-1: 10.0.2.1
    ├─ RS-2: 10.0.2.2
    └─ RS-3: 10.0.2.3
完整配置实战

步骤 1:网络规划

复制代码
# LVS 服务器
VIP=1.2.3.100          # 对外服务 IP
DIP_LVS1=10.0.1.10      # LVS-1 内网 IP
DIP_LVS2=10.0.1.11      # LVS-2 内网 IP

# 后端服务器
RIP1=10.0.2.1
RIP2=10.0.2.2
RIP3=10.0.2.3

# 服务端口
HTTP_PORT=80
HTTPS_PORT=443

步骤 2:配置 LVS 主节点

复制代码
#!/bin/bash

# 配置文件: /etc/lvs/lvs.conf

# 网络配置
VIP=1.2.3.100
VIP_NETMASK=255.255.255.255
DIP=10.0.1.10
INTERFACE=eth0

# 配置 VIP
ip addr add ${VIP}/${VIP_NETMASK} dev ${INTERFACE}

# 启用 IP 转发(如果使用 NAT 模式)
echo 1 > /proc/sys/net/ipv4/ip_forward

# 清空现有规则
ipvsadm -C

# 配置虚拟服务(使用 DR 模式)
ipvsadm -A -t ${VIP}:${HTTP_PORT} -s wlc --persistent 3600
ipvsadm -A -t ${VIP}:${HTTPS_PORT} -s wlc --persistent 3600

# 添加后端服务器
ipvsadm -a -t ${VIP}:${HTTP_PORT} -r 10.0.2.1:${HTTP_PORT} -g -w 100
ipvsadm -a -t ${VIP}:${HTTP_PORT} -r 10.0.2.2:${HTTP_PORT} -g -w 100
ipvsadm -a -t ${VIP}:${HTTP_PORT} -r 10.0.2.3:${HTTP_PORT} -g -w 100

ipvsadm -a -t ${VIP}:${HTTPS_PORT} -r 10.0.2.1:${HTTPS_PORT} -g -w 100
ipvsadm -a -t ${VIP}:${HTTPS_PORT} -r 10.0.2.2:${HTTPS_PORT} -g -w 100
ipvsadm -a -t ${VIP}:${HTTPS_PORT} -r 10.0.2.3:${HTTPS_PORT} -g -w 100

# 保存规则
ipvsadm-save > /etc/ipvsadm.conf

# 查看配置
ipvsadm -Ln

步骤 3:配置后端服务器

复制代码
#!/bin/bash

# 在每个后端服务器上执行

VIP=1.2.3.100
INTERFACE=eth0

# 方法 1: 临时配置
ifconfig lo:0 ${VIP} netmask 255.255.255.255 up

# 方法 2: 永久配置
cat >> /etc/network/interfaces << EOF
auto lo:0
iface lo:0 inet static
    address ${VIP}
    netmask 255.255.255.255
EOF

# 配置 ARP 抑制(DR 模式必需)
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/${INTERFACE}/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/${INTERFACE}/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

# 验证配置
ip addr show lo:0

步骤 4:配置 Keepalived 高可用

复制代码
#!/bin/bash

# LVS 主节点配置: /etc/keepalived/keepalived.conf
cat > /etc/keepalived/keepalived.conf << 'EOF'
! Configuration File for keepalived

global_defs {
   notification_email {
     admin@example.com
   }
   notification_email_from lvs@example.com
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

# VIP 配置
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        1.2.3.100
    }
}

# HTTP 健康检查
virtual_server 1.2.3.100 80 {
    delay_loop 6
    lb_algo wlc
    lb_kind DR
    persistence_timeout 3600
    protocol TCP
    
    real_server 10.0.2.1 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
    
    real_server 10.0.2.2 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
    
    real_server 10.0.2.3 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
}

# HTTPS 健康检查
virtual_server 1.2.3.100 443 {
    delay_loop 6
    lb_algo wlc
    lb_kind DR
    persistence_timeout 3600
    protocol TCP
    
    real_server 10.0.2.1 443 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 443
        }
    }
    
    real_server 10.0.2.2 443 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 443
        }
    }
    
    real_server 10.0.2.3 443 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 443
        }
    }
}
EOF

# 启动 Keepalived
systemctl start keepalived
systemctl enable keepalived
流量均衡策略优化

场景 1:静态资源服务

对于图片、CSS、JS 等静态资源,推荐使用加权轮询算法:

复制代码
# 假设 RS-3 性能更好
ipvsadm -A -t 1.2.3.100:80 -s wrr
ipvsadm -a -t 1.2.3.100:80 -r 10.0.2.1:80 -g -w 100
ipvsadm -a -t 1.2.3.100:80 -r 10.0.2.2:80 -g -w 100
ipvsadm -a -t 1.2.3.100:80 -r 10.0.2.3:80 -g -w 200

场景 2:动态 API 服务

对于需要长连接的 API 服务,使用最小连接算法:

复制代码
ipvsadm -A -t 1.2.3.100:80 -s lc --persistent 1800

场景 3:需要会话保持的服务

对于需要保持用户会话的服务(如购物车),使用源地址哈希:

复制代码
ipvsadm -A -t 1.2.3.100:80 -s sh --persistent 7200

2.2 提供内网 VIP 和 IDC 内部服务

内网 VIP 配置相对简单,但需要根据服务特性选择合适的策略。

典型场景:MySQL 读写分离
复制代码
#!/bin/bash

# 配置写 VIP(只转发到 Master)
VIP_WRITE=10.1.1.101
VIP_READ=10.1.1.102

# 写服务:单后端
ipvsadm -A -t ${VIP_WRITE}:3306 -s rr
ipvsadm -a -t ${VIP_WRITE}:3306 -r 10.1.2.1:3306 -g

# 读服务:多后端负载均衡
ipvsadm -A -t ${VIP_READ}:3306 -s wlc
ipvsadm -a -t ${VIP_READ}:3306 -r 10.1.2.2:3306 -g -w 100
ipvsadm -a -t ${VIP_READ}:3306 -r 10.1.2.3:3306 -g -w 100
ipvsadm -a -t ${VIP_READ}:3306 -r 10.1.2.4:3306 -g -w 100
微服务网关负载均衡
复制代码
#!/bin/bash

# 微服务网关负载均衡
VIP_GATEWAY=10.1.1.120

# HTTP 服务
ipvsadm -A -t ${VIP_GATEWAY}:80 -s wlc --persistent 300
for rs in 10.1.3.1 10.1.3.2 10.1.3.3; do
    ipvsadm -a -t ${VIP_GATEWAY}:80 -r ${rs}:80 -g -w 100
done

# HTTPS 服务
ipvsadm -A -t ${VIP_GATEWAY}:443 -s wlc --persistent 300
for rs in 10.1.3.1 10.1.3.2 10.1.3.3; do
    ipvsadm -a -t ${VIP_GATEWAY}:443 -r ${rs}:443 -g -w 100
done

2.3 SNAT 集群与外网访问

某些 IDC 没有公网出口,需要通过 SNAT 集群访问外网。

SNAT 配置
复制代码
#!/bin/bash

# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 配置 SNAT 规则
INTERNAL_NETWORK=10.1.0.0/16
EXTERNAL_IP=1.2.3.100

iptables -t nat -A POSTROUTING \
    -s ${INTERNAL_NETWORK} \
    -j SNAT --to-source ${EXTERNAL_IP}

# 保存规则
iptables-save > /etc/iptables/rules.v4
SNAT 集群高可用

配合 Keepalived 实现 SNAT 集群:

复制代码
#!/bin/bash

# Keepalived 配置
cat > /etc/keepalived/keepalived.conf << 'EOF'
vrrp_instance VI_SNAT {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 100
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass snat123
    }
    
    virtual_ipaddress {
        1.2.3.100
    }
}
EOF

2.4 服务隔离和安全控制

VLAN 隔离
复制代码
# 配置 VLAN 接口
vconfig add eth0 100
ip addr add 10.1.1.10/24 dev eth0.100
ip link set eth0.100 up

# 配置 VIP
ip addr add 10.1.1.100/32 dev eth0.100
防火墙规则
复制代码
#!/bin/bash

# 允许特定内网网段访问
iptables -A INPUT -p tcp -s 10.1.0.0/16 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp -s 10.1.0.0/16 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp -s 10.1.0.0/16 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 10.1.0.0/16 --dport 443 -j ACCEPT

# 拒绝其他访问
iptables -A INPUT -p tcp --dport 3306 -j DROP
iptables -A INPUT -p tcp --dport 6379 -j DROP
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

第三章:高可用架构

3.1 使用 Keepalived 做健康检查

Keepalived 是 LVS 生态中最重要的高可用工具,它通过 VRRP 协议实现 VIP 漂移,并内置了健康检查机制。

Keepalived 架构
复制代码
┌─────────────────────────────────────────┐
│           Keepalived                    │
├─────────────┬───────────┬───────────────┤
│ VRRP Stack  │  Checkers │  IPVS Wrapper  │
│ (VIP管理)   │ (健康检查) │ (规则同步)     │
└──────┬──────┴─────┬─────┴───────┬───────┘
       │            │             │
    ┌──▼──┐     ┌───▼────┐   ┌───▼────┐
    │eth0 │     │backend  │   │backend │
    │VIP  │     │check    │   │check   │
    └─────┘     └─────────┘   └─────────┘
健康检查类型

1. TCP_CHECK:检查 TCP 端口是否可连接

复制代码
real_server 10.0.2.1 80 {
    weight 100
    TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
    }
}

2. HTTP_GET:检查 HTTP 状态码

复制代码
real_server 10.0.2.1 80 {
    weight 100
    HTTP_GET {
        url {
            path /health
            status_code 200
        }
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
    }
}

3. SSL_GET:检查 HTTPS 状态码

复制代码
real_server 10.0.2.1 443 {
    weight 100
    SSL_GET {
        url {
            path /health
            status_code 200
        }
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
    }
}

4. MISC_CHECK:自定义脚本检查

复制代码
real_server 10.0.2.1 80 {
    weight 100
    MISC_CHECK {
        misc_path "/usr/local/bin/check_app.sh 10.0.2.1"
        misc_timeout 10
    }
}

3.2 使用 VRRP 实现主备

VRRP (Virtual Router Redundancy Protocol) 是 Keepalived 实现 VIP 漂移的核心协议。

VRRP 工作原理
复制代码
时间轴:
t0  t1  t2  t3  t4  t5  t6  t7  t8  t9  t10
│   │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │   │
L1: M   ●   ●   ●   ●   ●   ●   ●   ●   ●   (主节点)
L2: B   □   □   □   □   □   □   □   □   □   (备节点)

M = MASTER 发送广播
● = 正常运行
B = BACKUP 监听
□ = 等待状态

故障场景:
t6 时主节点故障
t7 时备节点检测到主节点停止广播
t8 时备节点提升为主节点
VRRP 配置详解
复制代码
#!/bin/bash

# 主节点配置
cat > /etc/keepalived/keepalived.conf << 'EOF'
vrrp_instance VI_1 {
    state MASTER              # 状态:MASTER/BACKUP
    interface eth0            # 监听接口
    virtual_router_id 51      # 虚拟路由 ID(必须一致)
    priority 100              # 优先级(主节点更高)
    advert_int 1              # 广播间隔(秒)
    
    # 认证
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    # VIP
    virtual_ipaddress {
        1.2.3.100
    }
    
    # 通知脚本(可选)
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}
EOF
通知脚本
复制代码
#!/bin/bash

# /etc/keepalived/notify.sh
TYPE=$1
case $TYPE in
    master)
        echo "Become MASTER" >> /var/log/keepalived.log
        # 执行主节点特定操作
        ;;
    backup)
        echo "Become BACKUP" >> /var/log/keepalived.log
        # 执行备节点特定操作
        ;;
    fault)
        echo "FAULT detected" >> /var/log/keepalived.log
        # 执行故障处理
        ;;
esac

3.3 使用 ECMP 实现集群化

ECMP (Equal-Cost Multi-Path) 是一种更高级的集群化方案,可以实现多主架构。

ECMP 架构
复制代码
                      [路由器]
                         │
         ┌───────────────┼───────────────┐
         │               │               │
      ┌──▼──┐         ┌──▼──┐         ┌──▼──┐
      │LVS1 │         │LVS2 │         │LVS3 │
      │VIP  │         │VIP  │         │VIP  │
      └──┬──┘         └──┬──┘         └──┬──┘
         │               │               │
         └───────────────┼───────────────┘
                         │
                  ┌──────┴──────┐
                  │             │
               ┌──▼──┐       ┌──▼──┐
               │ RS1 │       │ RS2 │
               └─────┘       └─────┘

路由器维护等价路由表:
1.2.3.100 -> LVS1 (权重: 1)
1.2.3.100 -> LVS2 (权重: 1)
1.2.3.100 -> LVS3 (权重: 1)

流量按哈希分发到不同 LVS 节点
路由器配置(假设使用 Cisco)
复制代码
! 配置 ECMP
ip route 1.2.3.100 255.255.255.255 10.0.1.10
ip route 1.2.3.100 255.255.255.255 10.0.1.11
ip route 1.2.3.100 255.255.255.255 10.0.1.12
BGP ECMP

在大规模环境中,可以使用 BGP 实现 ECMP:

复制代码
# 在每个 LVS 节点上配置 BGP
# 宣告相同的 VIP 路由
router bgp 65001
 bgp router-id 10.0.1.10
 neighbor 10.0.0.1 remote-as 65000
 !
 address-family ipv4
  network 1.2.3.100 mask 255.255.255.255
  neighbor 10.0.0.1 activate
 exit-address-family

3.4 使用网卡绑定扩展单网卡流量

当单网卡带宽成为瓶颈时,可以使用网卡绑定(Bonding)技术。

Bonding 模式

mode 0 (balance-rr) :轮询模式mode 1 (active-backup) :主备模式mode 4 (802.3ad):LACP 聚合模式

配置示例
复制代码
#!/bin/bash

# 加载 bonding 模块
modprobe bonding mode=4 miimon=100

# 创建 bond0 接口
cat > /etc/network/interfaces << EOF
auto bond0
iface bond0 inet static
    address 10.0.1.10
    netmask 255.255.255.0
    bond-mode 4
    bond-miimon 100
    bond-slaves eth0 eth1 eth2

auto eth0
iface eth0 inet manual
    bond-master bond0

auto eth1
iface eth1 inet manual
    bond-master bond0

auto eth2
iface eth2 inet manual
    bond-master bond0
EOF

# 重启网络
systemctl restart networking

# 验证
cat /proc/net/bonding/bond0

第四章:横向扩展

4.1 扩展负载均衡器

当单个 LVS 集群无法满足流量需求时,需要进行横向扩展。

扩展方案

方案 1:多级 LVS

复制代码
用户
  ↓
[第一级 LVS 集群] (VIP: 1.2.3.100)
  ↓
[第二级 LVS 集群 A] (VIP: 10.1.1.10)
[第二级 LVS 集群 B] (VIP: 10.1.1.11)
[第二级 LVS 集群 C] (VIP: 10.1.1.12)
  ↓
[后端服务器集群]

方案 2:DNS 负载均衡 + LVS 集群

复制代码
DNS: www.example.com
  ├─ 1.2.3.100 (LVS 集群 A)
  ├─ 1.2.3.101 (LVS 集群 B)
  └─ 1.2.3.102 (LVS 集群 C)
多级 LVS 配置
复制代码
# 第一级 LVS 配置
ipvsadm -A -t 1.2.3.100:80 -s wlc
ipvsadm -a -t 1.2.3.100:80 -r 10.1.1.10:80 -g -w 100
ipvsadm -a -t 1.2.3.100:80 -r 10.1.1.11:80 -g -w 100
ipvsadm -a -t 1.2.3.100:80 -r 10.1.1.12:80 -g -w 100

# 第二级 LVS 配置(集群 A)
ipvsadm -A -t 10.1.1.10:80 -s wlc
ipvsadm -a -t 10.1.1.10:80 -r 10.2.1.1:80 -g -w 100
ipvsadm -a -t 10.1.1.10:80 -r 10.2.1.2:80 -g -w 100

4.2 扩展后端服务器

后端服务器的扩展相对简单,只需在 LVS 配置中添加新的后端服务器。

动态添加后端服务器
复制代码
# 添加新的后端服务器
ipvsadm -a -t 1.2.3.100:80 -r 10.0.2.10:80 -g -w 100

# 调整权重
ipvsadm -e -t 1.2.3.100:80 -r 10.0.2.10:80 -g -w 200

# 临时移除(不删除配置)
ipvsadm -d -t 1.2.3.100:80 -r 10.0.2.10:80

# 永久删除
ipvsadm -D -t 1.2.3.100:80 -r 10.0.2.10:80
后端服务器预热

新添加的后端服务器可能需要预热:

复制代码
#!/bin/bash

# 逐步增加权重
NEW_RS=10.0.2.10
VIP=1.2.3.100

# 初始权重 10
ipvsadm -a -t ${VIP}:80 -r ${NEW_RS}:80 -g -w 10

# 逐步增加
for weight in 20 40 60 80 100; do
    sleep 60
    ipvsadm -e -t ${VIP}:80 -r ${NEW_RS}:80 -g -w ${weight}
done

第五章:多机房架构

5.1 使用 BGP Anycast 实现多个 IDC 负载均衡

BGP Anycast 是实现多机房负载均衡和机房灾备的高级方案。

Anycast 原理
复制代码
同一个 IP 地址 1.2.3.100 在多个机房宣告
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  北京机房   │    │  上海机房   │    │  广州机房   │
│  1.2.3.100  │    │  1.2.3.100  │    │  1.2.3.100  │
└──────┬──────┘    └──────┬──────┘    └──────┬──────┘
       │                  │                  │
       └──────────────────┼──────────────────┘
                          │
                   [互联网骨干网]

用户在北京:
  路由表: 1.2.3.100 -> 北京机房 (AS 路径最短)
  流量: 用户 -> 北京机房

用户在上海:
  路由表: 1.2.3.100 -> 上海机房 (AS 路径最短)
  流量: 用户 -> 上海机房
BGP Anycast 配置
复制代码
#!/bin/bash

# 北京机房配置
cat > /etc/quagga/bgpd.conf << 'EOF'
router bgp 65001
 bgp router-id 10.0.1.1
 neighbor 10.0.0.1 remote-as 65000
 neighbor 10.0.0.2 remote-as 65000
 !
 address-family ipv4 unicast
  network 1.2.3.100 mask 255.255.255.255
  neighbor 10.0.0.1 activate
  neighbor 10.0.0.2 activate
 exit-address-family
!
 line vty
EOF

# 启动 BGP
systemctl start bgpd
机房灾备

当一个机房故障时,BGP 路由会自动切换:

复制代码
# 模拟北京机房故障
# 停止 BGP 宣告
systemctl stop bgpd

# 流量自动切换到上海和广州机房

5.2 多机房会话保持

多机房环境下,会话保持更加复杂。

方案 1:全局 Session 存储
复制代码
北京机房 ─┐
上海机房 ─┼─→ Redis 集群(跨机房)
广州机房 ─┘
方案 2:Anycast + 会话绑定
复制代码
# 使用源地址哈希算法
# 同一用户的请求总是路由到同一机房
ipvsadm -A -t 1.2.3.100:80 -s sh --persistent 7200

性能优化与调优

内核参数调优

复制代码
#!/bin/bash

# 网络核心参数
echo 1 > /proc/sys/net/ipv4/ip_forward

# 连接跟踪
echo 1048576 > /proc/sys/net/netfilter/nf_conntrack_max
echo 86400 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
echo 120 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait

# TCP 参数
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 1024 65535 > /proc/sys/net/ipv4/ip_local_port_range

# 文件描述符
echo 1000000 > /proc/sys/fs/file-max

# 永久配置
cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward = 1
net.netfilter.nf_conntrack_max = 1048576
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 1000000
EOF

sysctl -p

LVS 参数调优

复制代码
# 连接超时设置
ipvsadm --set 1200 60 300

# 参数说明:
# 第一个值:TCP 连接超时(秒)
# 第二个值:TCP FIN 超时(秒)
# 第三个值:UDP 超时(秒)

监控指标

复制代码
#!/bin/bash

# 监控脚本
while true; do
    echo "=== LVS 监控 ==="
    date
    
    # 查看连接数
    ipvsadm -Ln --rate
    
    # 查看统计信息
    ipvsadm -Ln --stats
    
    # 查看 CPU 使用率
    top -b -n 1 | head -20
    
    # 查看网络流量
    sar -n DEV 1 1
    
    sleep 60
done

故障排查指南

常见问题诊断

问题 1:后端服务器无法接收流量

复制代码
# 检查 VIP 配置
ip addr show | grep 1.2.3.100

# 检查 ARP 抑制
cat /proc/sys/net/ipv4/conf/all/arp_ignore
cat /proc/sys/net/ipv4/conf/all/arp_announce

# 检查 LVS 规则
ipvsadm -Ln

# 抓包分析
tcpdump -i eth0 host 1.2.3.100 -n

问题 2:流量分发不均

复制代码
# 查看连接分布
ipvsadm -Ln --rate

# 检查调度算法
ipvsadm -Ln | grep "Scheduler"

# 调整权重
ipvsadm -e -t 1.2.3.100:80 -r 10.0.2.1:80 -w 200

问题 3:VIP 漂移失败

复制代码
# 检查 Keepalived 状态
systemctl status keepalived

# 检查 VRRP 广播
tcpdump -i eth0 vrrp -n

# 检查防火墙
iptables -L INPUT -v

0voice · GitHub

相关推荐
荣--14 小时前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森15 小时前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜1 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB2 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode4 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220704 天前
如何搭建本地yum源(上)
运维
大树887 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠7 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质7 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工7 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信