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

相关推荐
wanhengidc2 小时前
服务器该如何防范网络攻击?
运维·服务器·网络·网络协议·安全·web安全·智能手机
是垚不是土2 小时前
Kafka 故障排查周期长?试试 Kdoctor
linux·运维·分布式·ai·kafka·运维开发
学术小白人2 小时前
广州高博科技|以科技赋能科研,做学术文明的摆渡人与科研加速器
运维·人工智能·科技·制造·rdlink研发家·数字能源
野木香2 小时前
linux安装常用服务(不含jenkins)
linux·运维·jenkins
计算机安禾2 小时前
【Linux从入门到精通】第8篇:用户与权限管理(上)——谁动了我的文件?
linux·运维·服务器
艾莉丝努力练剑2 小时前
【Linux线程】Linux系统多线程(九):线程池实现(附代码示例)
linux·运维·服务器·c++·学习·架构
晨晖22 小时前
linux笔记6
linux·运维·笔记
bukeyiwanshui2 小时前
20260420 Nginx 服务器
运维·服务器·nginx
xingyuzhisuan2 小时前
警惕“套牌”4090:如何辨别服务器用的是不是真卡?
运维·服务器·gpu算力