第一章: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 先定义标准的 "插座",当你要注册一个协议时,系统会分配一个新 "插头" 并插到插座上。
设计优势:
- 灵活性高:支持新协议无需改动核心代码,只需开发新插件
- 扩展性强:可以动态加载 / 卸载协议模块
- 维护性好:各协议模块独立,便于调试和优化
负载均衡调度机制
Hash 链表与调度算法
当数据包进入 IPVS 时,处理流程如下:
- 查找阶段:先检查 Hash 表,判断是否已有连接
- 调度阶段 :如果是新连接,调用
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 插件,负责:
- 检测 FTP 协议(主动 / 被动模式)
- 提取 Payload 中的 IP 地址和端口
- 将内网 IP 替换为 LVS 的外网 IP
- 重新计算 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