资讯动态

LVS负载均衡原理与实战:从IPVS调度算法到高并发集群DR模式配置

发布时间:2026/10/9 7:15:03 来源:尧图企业网站定制
1. LVS是什么为什么高并发集群里总能看到它的身影LVS负载均衡全称Linux Virtual Server是由章文嵩博士在1998年发起的一个开源项目也是国内技术圈少有的、真正走向世界的底层网络方案。它在Linux内核层面直接实现了IP层L3的负载均衡调度简单说就是请求到达负载均衡器时内核中的IPVS模块会根据预设的调度算法决定把数据包转给哪个后端真实服务器处理。这个决策过程完全在内核态完成不需要像Nginx那样经过用户态协议栈解析所以吞吐能力和并发承载量非常惊人。我最初接触LVS是因为公司线上服务扛不住流量冲击当时Nginx已经跑到单机四万多连接CPU频繁被打满业务方还在持续扩容。后来架构师把入口层的负载均衡换成了LVS同样规格的机器轻轻松松撑住了百万级别并发连接那一刻我才真正意识到同样是做负载均衡数据链路层面和用户态层面的效率差距可能是数量级的。这篇文章适合正在做网络架构选型、处理大规模流量入口问题或者单纯想理解Linux内核网络栈如何参与流量分发的读者。我会顺着一条请求从进入到返回的完整路径把LVS的核心机制、三种工作模式、调度算法以及生产环境的配置方法全部拆开讲一遍最后附上我实际踩过的坑和排查经验尽量做到从原理到落地一次讲透。2. 核心架构拆解LVS如何在数据链路层完成“高效调度”2.1 三个核心组件各自扮演什么角色LVS整个体系由三部分组成负载调度器Director、服务器池Real Server Pool以及共享存储可选。很多人第一次看架构图会把注意力集中在调度器和后端服务器的关系上但真正理解LVS要先搞明白调度器内部的工作机制。调度器上运行着两个关键东西一个是内核态的IPVSIP Virtual Server模块它负责实际的数据包改写和转发这是LVS能够高效工作的灵魂另一个是用户态的ipvsadm工具它负责管理员跟IPVS之间的交互——比如创建虚拟服务、添加后端节点、查看统计信息全部通过ipvsadm来操作。你可以把IPVS理解成发动机本身ipvsadm则是驾驶室里的方向盘和仪表盘。这里有个很重要的细节IPVS从2.4内核之后就已经合入Linux主分支了也就是说现在任何一台标准发行版Linux机器上都自带了LVS的能力只是默认没有开启。安装时只需要把ipvsadm装好然后在内核模块里加载对应项即可不需要重新编译内核。这一点让LVS的部署成本很低和你装个tcpdump差不多简单但它的能力上限却是千万级连接。2.2 一条请求从进门到出门的完整数据流我用自己的话描述一下VS/DR模式下一个数据包的完整旅程理解了这条路径后面的配置才会真正变成“有逻辑”而不是“背参数”。客户端发送一个TCP SYN包给调度器上配置的虚拟IPVIP。由于VIP配置在调度器的网卡上通常是一个绑定的辅助IP网卡收到这个帧后交给内核协议栈。IPVS模块在Netfilter的LOCAL_IN钩子点上注册了处理逻辑发现目标IP匹配到某个虚拟服务规则后不会把它交给用户态进程而是立即进入调度流程。调度器根据预设的调度算法从后端列表中选出一台真实服务器RIP然后做两件关键事情修改数据包的MAC目的地址为选中后端服务器的MAC同时把数据包的目标IP保持不变。这里要特别注意VS/DR模式下数据包经过调度器时的IP地址是不变的变的只有MAC帧头。改写完成后数据包从调度器的物理网卡发出去此时它已经是在二三层网络中“定向”发给某台后端服务器的包了。后端服务器收到这个包它上面也配置了VIP作为lo接口的辅助地址。因为我们提前设置了内核参数arp_ignore和arp_announce后端服务器不会对外宣告自己拥有VIP所以它能收到调度器转来的包但不会引发ARP冲突。后端处理完请求把响应包直接以VIP作为源地址回给客户端——注意这一步不经过调度器是后端服务器自己通过网关出去的。整个过程调度器只在请求入口参与了一次MAC改写响应流量完全绕开了它这也是VS/DR模式能支撑超高吞吐量的根本原因。Nginx做负载均衡时进出流量都必须穿透Nginx进程LVS在DR模式下相当于让调度器只负责“分流”后端直连地回包链路开销小到可以忽略。3. 三种工作模式对比选型之前先看懂原理LVS有三种经典工作模式分别解决不同场景下的不同瓶颈很多文章只会列对比表格但我要先讲清楚每个模式背后的取舍逻辑不然换一个环境你可能就不知道怎么选了。3.1 VS/NAT模式最省IP但容易成为瓶颈VS/NAT模式最容易理解调度器在这里充当一个“路由器”负责改写数据包的源IP和目标IP转发给后端的私网服务器后端服务器响应时把包再还给调度器由调度器改写源IP为VIP后发给客户端。这种模式下后端服务器只需要私网地址省公网IP也方便统一出网安全策略。但问题在于请求和响应都要经过调度器进出流量全都压在这台机器上。当响应体较大、或者下载类业务居多时调度器的网卡吞吐就成了硬瓶颈。我见过一台双千兆网卡的NAT模式调度器跑到将近2Gbps流量时CPU和网卡中断就开始频繁报警了。所以我的建议是小规模业务、服务器网段分配紧张、或者后端安全性要求较高的场景下考虑VS/NAT一旦预估稳态流量超过1Gbps就不要让调度器承接回程压力了。3.2 VS/TUN模式调度与转发解耦VS/TUN模式引入了IP隧道概念调度器把原始数据包封装在一个新的IP包里外层源IP是调度器内网IP外层目标IP是后端服务器的IP。后端服务器收到后自行解封装处理完请求直接以VIP为源回包给客户端。这个模式的核心好处是调度器和后端不需要在同一个二层网络内可以跨网段调度。因为封装转发的是IP包依靠路由可达即可。代价也很明显封装和解封装有额外的CPU开销同时后端服务器需要支持隧道模块并正确配置VIP而且外网路由必须能允许这个VIP直接从后端出去。实际生产中TUN用得远不如DR多。一方面大多数业务场景的调度器和后端本来就在同一机房二层内DR模式可用另一方面隧道封装带来的MTU问题和性能损耗让人头疼。除非你有非常明确的跨网段调度需求否则我会建议优先看DR。3.3 VS/DR模式生产环境里的绝对主力VS/DR模式我在前面已经写过数据流了这里重点说它的适用条件调度器和所有后端服务器必须在同一个二层广播域内通常同一个交换机或者同一套VLAN。因为调度器改写的只是MAC地址路由器没法跨三层帮你找到后端的RIP。DR模式是生产环境中用得最多的原因很朴素它没有隧道封装开销响应流量绕过调度器支持的系统吞吐上限最高。同时DR模式不修改数据包的端口所以像HTTP、HTTPS、TCP长连接这类服务几乎都能透明代理调度配合Keepalived做高可用之后基本是标准答案级别的方案。选型时的判断口诀我个人总结为同二层优先DR跨网段用TUN后端私网且流量不大用NAT。3.4 三种模式对照表对比维度VS/NATVS/TUNVS/DR后端网络要求私网即可跨网段路由可达与调度器同二层调度器压力进出都经过压力最大进经过出绕过仅入口改写MAC数据包修改IP层改动IP封装MAC帧头改写后端系统要求无特殊支持隧道模块lo配置VIP并抑制ARP吞吐上限较低中等最高典型适用小规模/安全要求高跨机房调度大规模高并发入口4. 调度算法全解析从轮询到最小连接的选择智慧IPVS支持十种调度算法很多人第一次看到这么一堆算法名会懵但只要按“静态”和“动态”两类去理解思路就清晰了。4.1 静态调度算法家族静态算法的特点是决策时只看预设权重或固定规则不参考后端当前连接数、负载情况。轮询算法rr最简单请求按顺序挨个发给后端就像是食堂打菜窗口排队轮到谁就是谁。加权轮询wrr在其上增加了权重高配置机器分到的请求数量比例更高。目标地址散列dh和源地址散列sh则根据目标或源IP做哈希映射同一个IP的请求始终落到同一台后端本质上是把调度问题变成了取模问题。静态族的优点是零状态调度开销极小极端情况下也不会因为统计连接数而引入性能损耗。缺点是“看不见后端状态”假设某台后端连接池满了后续请求照样按轮询塞过去可能导致延迟雪崩。所以生产环境我一般不会直接用纯轮询除非后端应用本身是无状态且能横向无限扩容的。4.2 动态调度算法家族动态算法会查看后端的当前连接数、响应时间等实时状态来做决策。最少连接算法lc选择当前连接数最小的后端就像银行柜台哪个窗口排队的人少就去哪个。加权最少连接wlc在lc之上加入权重修正避免权重配置高的机器因为连接数少反而被过度倾斜。最短期望延迟sed估算每台后端完成请求的期望时间取最小者。最少队列调度nq是sed的变体主要避免权重大的机器永远空闲或排在前面。我最常用的其实是wlc它在大多数场景下表现均衡且配置简单。但要注意wlc里“连接数”是IPVS自己维护的它只管TCP连接建立和拆除如果后端有长连接池复用IPVS看到连接数可能失真。比如后端是MySQL或Redis这类长连接服务你觉得连接数分布均匀实际上某几台的业务线程可能早就处理不过来了。面对这种情况我建议先确认后端业务是否适合连接数作为调度指标再决定算法选型必要时还得回归到sh这种确定性哈希。4.3 如何合理选择算法选择算法没有银弹我给出一些自己实测过的场景建议常规HTTP短连接集群优先wlc同时把后端权重按实际性能拉齐。长连接场景数据库代理、消息队列客户端等推荐sh或基于数据特征的调度保证同一客户端IP始终连同一后端发挥连接复用优势。WebSocket或推送类服务用sh或pcc方式让连接生命周期内请求绑定在同一节点避免跨节点状态同步问题。后端处理能力差异明显用wrr或wlc配合权重校准不要靠rr去赌运气。顺带说一句调度算法和“一致性哈希”这类分布式缓存方案的思想是相通的——你在设计调度策略时要思考的关键永远是你的后端是有状态还是无状态、连接是否可复用、流量是否倾斜。想通了这一点任何调度器在你眼里都只是工具集而不是需要背参数的黑盒子。5. 实操VS/DR模式完整配置记录5.1 环境规划与参数计算我在测试环境里用三台机器模拟生产拓扑调度器Director192.168.1.10承载VIP 192.168.1.100后端一RS1192.168.1.11运行Nginx权重2后端二RS2192.168.1.12运行Nginx权重1客户端机192.168.1.200仅用于发送压测请求这里解释一下权重为什么设为2比1RS1的CPU核数是4核RS2是2核按照“处理能力比带宽和内存更关键”的原则我直接按核数比例给了权重。如果你后端的瓶颈可能是内存或磁盘权重也应该跟着瓶颈资源的能力来定不要把权重当成玄学去调。5.2 配置步骤第一步在调度器上确认内核支持并安装ipvsadm# 确认内核模块存在 modprobe ip_vs lsmod | grep ip_vs # 安装管理工具以Ubuntu/Debian为例 apt-get install -y ipvsadm第二步配置调度器网卡VIP# 在eth0上添加VIP子网掩码跟物理网卡保持一致即可 ifconfig eth0:0 192.168.1.100 netmask 255.255.255.0 up这里有个细节VIP的子网掩码尽量和物理网卡一致。如果掩码写成了32位会导致同一个广播域内的其他机器无法通过ARP学习到VIP对应的MAC地址请求就进不来。我以前就因此排错排了一个小时最后发现是辅助接口掩码写错。第三步在调度器上配置虚拟服务、添加后端# 定义一个VIP为192.168.1.100、端口80的TCP虚拟服务调度算法为wlc ipvsadm -A -t 192.168.1.100:80 -s wlc # 添加两个后端节点开启权重-g表示使用DR模式 ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.11:80 -g -w 2 ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.12:80 -g -w 1 # 查看配置生效 ipvsadm -Ln第四步配置后端服务器。两台上都要把VIP绑定到loopback接口并抑制ARP# 绑定VIP到lo接口 ifconfig lo:0 192.168.1.100 netmask 255.255.255.255 up # 抑制ARP响应 echo 1 /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 /proc/sys/net/ipv4/conf/all/arp_announce echo 1 /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 /proc/sys/net/ipv4/conf/lo/arp_announcear p_ignore设为1的含义是“只有当ARP请求的目标IP是本机某网卡的IP时才响应”后端上的VIP虽然在lo上但如果别的机器广播询问VIP的MAC地址后端默认会响应——这就会造成VIP的MAC地址在局域网内混乱调度器发出的包可能被后端自己接收也可能被交换机错误转发。arp_announce设为2则限制本机ARP通告时尽量使用物理网卡IP作为源。这两个参数是DR模式不出问题的前提我反复强调它们因为不看文档的人几乎都会在这里翻车。第五步关闭后端所有对VIP的路由响应或转发干扰一般默认即可最后验证# 在客户端上持续请求 for i in $(seq 1 10); do curl -s http://192.168.1.100/; done # 在调度器上查看连接分布 ipvsadm -Lnc正常情况你会看到IPVS统计了每个后端的活跃连接数并且权重2的RS1连接数大约接近权重1的RS2的两倍。如果所有请求都落在同一台上先检查后端ARP抑制是否生效再用ipvsadm -Lnc看调度器实际转发到了哪个RIP逐层定位。5.3 关于Keepalived的补充生产环境不会让调度器成为单点通常会用Keepalived在至少两台调度器之间漂移VIP。Keepalived通过VRRP协议实现主备自动切换同时还能做后端健康检查定期检查后端端口存活发现异常自动摘除节点。这一步我强烈建议一并在生产落地时加上否则调度器宕机整站全挂后端宕机流量还会被打到坏节点。配置不算复杂Keepalived里写好vrrp_instance和virtual_server段即可网上模板很多但记住先把基础DR模式LVS调通再加高可用层别上来就两把梭哈排错会非常困难。6. 高频问题与排查技巧实录6.1 后端能收到包但业务不通问题大概率在ARP和路由这是DR模式最经典的疑难杂症。表现是客户端curl VIP返回超时但登录到后端用tcpdump抓包能看到TCP握手包已经到达。这时候不要怀疑IPVS配置大概率是响应包没按预期回去。排查步骤我固定如下在后端上检查lo:0是否绑定且掩码是否为32位检查arp_ignore和arp_announce是否在all和lo两个作用域都生效检查后端的默认路由是否是真实网关响应包源IP是不是VIP。只要其中一环出错客户端发来的SYN包到了后端但后端回包时发现源IP是VIP却没有对应出接口或被抓包系统丢进lo又出不去客户端就一直收不到SYN-ACK。我还遇到过一种隐蔽情况后端上同时跑着多网卡物理网卡的默认路由指向了内网某个不对的网关导致VIP响应包被路由到不可达网络。所以检查路由表时不要只看有没有默认路由还要确认这条默认路由的下一跳确实能通到客户端侧网络。6.2 调度权重不均匀怎么办有次我做压测明明配置了wlc调度器统计里却发现两台后端连接数一直纠缠在一起RS2总比RS1少四分之一左右。最初以为是权重参数没有生效反复重载IPVS结果依旧。后来看了后端RS2网卡的中断合并策略才发现那台机器网卡催收队列的CPU亲和性配置有问题导致它在高并发下处理部分报文时发生大量重传连接建立变慢调度器侧看起来就是“这台机器连接数更少尽量少分配”。这个案例给我最大的教训是调度器侧的连接数统计不等于后端真实吞吐能力。当你发现分布和预期偏差大时第一步不要改算法或权重先看后端机器的CPU软中断分布、网卡队列状态、是否有重传。底层环境不稳任何调度策略都会建立在沙地上。6.3 健康检查的坑Keepalived只探端口是不够的很多团队用Keepalived做健康检查默认配置是TCP端口探测。这个方式只能证明后端进程还活着但证明不了业务可用。我之前趟过一次雷后端所有Nginx进程正常但由于某个上游服务挂掉Nginx返回大量5xxKeepalived却毫无反应流量继续灌进来用户体验就是一片报错。我现在的做法是在Keepalived的配置里用HTTP_GET健康检查或者用MISC_CHECK调用一段自定义脚本脚本内模拟真实请求并检查返回状态码和响应耗时。比如#!/bin/bash curl -s -o /dev/null -w %{http_code} http://127.0.0.1/healthcheck | grep -qE ^200|^302供应链层的一个小改动能避免业务层的大事故这个成本非常值得。6.4 并发连接暴涨时的“调度器CPU智能核心调度”玄机现在很多新网卡和多核CPU都在强调智能调度、多队列并行LVS在这种环境下乍一看很简单——反正核心够多就行。但实际操作中网络中断绑定RSS或RPS如果不设置CPU亲和性所有网卡队列中断都打在同一颗核上IPVS的转发能力会被单核中断锁死哪怕机器有64核也白搭。我给LVS服务器设定了一套固定的调优口诀网卡多队列全开并把各队列的中断绑定到不同CPU核心IPVS连接跟踪表大小按内存预调大开启IPVS连接复用和超时缩短避免TIME_WAIT堆积在调度器上。这套组合拳打下来调度器的单机吞吐会有非常可观的提升。具体的参数名字各内核版本略有差异你只要明白我上面的思路用ethtool和sysctl去调整即可不需要死记硬背某一个数值。7. 写在最后的一点个人经验LVS这套方案能活这么多年不是偶然它的设计思想本身就非常硬核在最底层解决最核心的流量分发问题把调度开销压缩到极致再把可扩展性留给业务层。我这些年见过不少团队因为觉得LVS配置“古老”而绕道去用各种新式网关结果遇到性能瓶颈时又回头来补内核参数的功课。我的体会是如果你想在高并发场景里活得舒服LVS Keepalived 合理的调度算法这套组合值得花时间彻底吃透。光会配三个命令在那敲一通没有用你得理解数据包在整个链路里到底经历了什么理解“为什么SERVER上要绑VIP”、“为什么ARP必须被抑制”、“为什么响应不回调度器”。把这些为什么想明白了你排障的速度和架构设计的分寸感都会有质的提升。最后再分享一个小技巧给生产环境的LVS配置做任何改动都先在测试环境里用tc或netem模拟丢包、延迟和重排观察调度器和后端在劣化网络下的行为。我靠这个方法提前发现过不止一个只有在恶劣链路下才会暴露的问题这种投入回报率非常高。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑