什么是 IPVS
Calendar 2026 年 1 月 20 日
Edit 共 1200 字,阅读需要 3 分钟

什么是 IPVS #

IPVS 是什么 #

IPVS (IP Virtual Server) 是 Linux 内核里的一个 L4 负载均衡子系统, 最早由章文嵩提出, 是 LVS (Linux Virtual Server) 项目的核心组件. 它主要用于高性能、可扩展的服务负载均衡场景.

nginx 也可以做 L4 负载均衡, 为什么需要 IPVS?

nginx 运行在用户态, 而 IPVS 运行在内核. 这导致两者性能有数量级的差距. 同时 IPVS 与 nginx 的工作方式也不同.

Linux 中使用 ipvsadm 来进行管理 IPVS 服务.

相关的术语:

  • VIP: Virtual IP, 服务对外暴露的 IP.
  • Director: 负载均衡部署的机器.
  • RS: Real Server, 真实部署服务的机器.

IPVS 的工作模式 #

IPVS 支持三种工作模式: NAT, DR, TUN:

  • NAT:
    • Director 做 DNAT + SNAT. 处理所有的流量.
    • 特点:
      • RS 不需要特殊网络配置.
      • 进出流量都经过 Director.
      • 性能一般.
    • 完整路径: Client -> Director -> RS -> Director -> Client
  • DR:
    • Director 只处理入流量. IPVS 将入站数据包的 MAC 地址修改为 RS 的 MAC 地址然后发出.
    • 特点:
      • RS 需要绑定 VIP 并关闭 ARP 响应.
      • 性能最好.
    • 完整路径: Client -> Director -> RS -> Client
  • TUN:
    • Director 用 IPIP 隧道把包发给 RS. 适用于 RS 与 Director 异地的场景. 性能接近 DR.
    • 完整路径: Client -> Director --(IPIP 隧道)-> RS -> Client

IPVS 的调度算法 #

  • rr: Round Robin. 轮询.
    • 请求按顺序一个个发给后端服务器.
    • 适用于服务器硬件配置基本一致且请求处理时间差不多的场景
  • wrr: Weighted Round Robin. 加权轮询.
    • 请求按权重发给后端服务器.
    • 适用于服务器性能不同且请求处理时间差不多的场景
  • dh: Destination Hash. 目标地址哈希.
    • 根据目标 IP 选服务器.
    • 同一个目标 IP 永远打到同一台 RS
  • sh: Source Hash. 源地址哈希.
    • 根据客户端 IP 选服务器.
    • 同一个客户端 IP 总是访问同一台 RS
    • 适用于需要会话粘性的场景
  • lc: Least Connection. 最少连接.
    • 选当前连接数最少的服务器
    • 适用于请求处理时间差异大, 有长连接 (如 API、数据库代理) 的场景
  • wlc: Weighted Least Connections. 加权最少连接.
    • 性能强的服务器即使连接多,也可能继续分配到
    • 评价标准为: 当前连接数 / 权重
  • sed: Shortest Expected Delay. 最短期望延迟.
    • 选「预测响应最快」的服务器. 比 wlc 更激进地倾向于空闲服务器.
    • 评价标准为: (当前连接数 + 1) / 权重
  • nq: Never Queue. 永不排队.
    • 在 sed 的基础上: 如果有空闲服务器 (0 连接), 立刻用它.
    • 适合低延迟系统 (RPC, 实时业务)

最常用的调度策略是 wlc

一个简单的示例 #

下面举一个简单的 DR 模式的负载均衡部署方案:

假设有一个 Director, 两个 RS. 对应的真实 IP 如下:

  • Director: 192.168.1.213
  • RS1: 192.168.1.220
  • RS1: 192.168.1.193

假设服务的 VIP 为 192.168.1.10. 调度算法使用 rr.

配置 Director #

安装 ipvsadm:

sudo apt install -y ipvsadm

将 VIP 绑定到网卡上. 在这里网卡名称为 ens18.

sudo ip addr add 192.168.1.10/32 dev ens18
sudo ip link set ens18 up

配置 IPVS. 这里采用轮询调度算法 rr.

# 清空现有规则
sudo ipvsadm -C

# 建立一个虚拟服务器 192.168.1.10:80, 采用轮询算法
sudo ipvsadm -A -t 192.168.1.10:80 -s rr

# 把 RS1 与 RS2 加入 VIP 的后端, 权重均为 1, 使用 DR 模式
sudo ipvsadm -a -t 192.168.1.10:80 -r 192.168.1.220:80 -g -w 1
sudo ipvsadm -a -t 192.168.1.10:80 -r 192.168.1.193:80 -g -w 1

# 查看 LVS 状态
sudo ipvsadm -Ln

输出如下:

$ sudo ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.1.10:80 rr
  -> 192.168.1.193:80             Route   1      0          0         
  -> 192.168.1.220:80             Route   1      0          0

配置 RS #

分别在两台 RS 上执行下面的操作:

绑定 VIP 到 loopback:

sudo ip addr add 192.168.1.10/32 dev lo
sudo ip link set lo up

配置 ARP 抑制:

# 只有当目标 IP 是本接口上的地址才响应 ARP
sudo sysctl -w net.ipv4.conf.all.arp_ignore=1
sudo sysctl -w net.ipv4.conf.lo.arp_ignore=1

# 对外宣告 ARP 时用更合适的源地址
sudo sysctl -w net.ipv4.conf.all.arp_announce=2
sudo sysctl -w net.ipv4.conf.lo.arp_announce=2

配置一个简单的 nginx 服务:

sudo apt-get -y install nginx

# RS2 写 RS2
sudo bash -c 'echo "RS1" > /var/www/html/index.html'

sudo systemctl enable --now nginx

测试 #

在局域网内任意一台机器上运行 curl 获取内容:

$ curl http://192.168.1.10/
RS1
$ curl http://192.168.1.10/
RS2
$ curl http://192.168.1.10/
RS1
$ curl http://192.168.1.10/
RS2

可以看到 RS1 与 RS2 交替返回.