我接手过不少LVS集群,说实话,ipvsadm -L -n这条命令大家都会敲,但真正能把输出里的Scheduler字段讲明白、并且按业务场景选对算法的人,并不多。很多人一套RR(轮询)走天下,或者干脆无脑选默认的WLC(加权最小连接),等到线上出现连接倾斜、响应变慢、缓存命中率下降,才回头怀疑调度策略出了问题。
这篇文章就把LVS调度算法这块彻底捋一遍:怎么查看当前算法、每种算法的原理和适用边界、以及我在实际运维中总结的选型经验。内容不追求教科书式的面面俱到,只讲生产环境真用得上、真会踩坑的部分。
1. 先搞清楚:LVS调度算法到底从哪里看
1.1 最常用的查看命令与其输出解读
如果你已经用ipvsadm配置好了LVS,查看当前虚拟服务器(VIP)使用的是什么调度算法,最直接的方式是:
bash复制ipvsadm -L -n
输出大概是这样的:
bash复制IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.100:80 wrr
-> 192.168.1.11:80 Route 1 0 0
-> 192.168.1.12:80 Route 2 0 0
-> 192.168.1.13:80 Route 3 0 0
里面几个关键点:
Scheduler这一列:就是当前这个VIP使用的调度算法,这里是wrr。Flags列:如果有值,通常是-p(持久性)或-6之类,它会影响调度行为,后面细讲。Weight列:每台真实服务器(RS)的权重,对wrr、wlc这类加权算法来说,这个数字直接决定分配比例。ActiveConn和InActConn:分别表示当前活跃连接数和非活跃连接数。前者是正在传输数据的TCP连接,后者是已经建立但暂时没有流量、或者处于TIME_WAIT等状态的连接。
只看这些还不够,我建议实际排障时把统计信息也打开:
bash复制# 查看累计连接数、进出包和字节数
ipvsadm -L -n --stats
# 查看每秒速率
ipvsadm -L -n --rate
# 查看超时时间配置
ipvsadm -L -n --timeout
--stats输出里有个Conn列,是累计到当前的总连接数,这个数字能侧面反映某个RS在历史上有没有被调度器“偏爱”。--rate则能看到CPS(每秒连接数)、InBPS(入带宽)、OutBPS(出带宽),用来验证权重调整是否生效非常实用。
1.2 查看内核实际支持的调度算法全家桶
有的朋友可能会问:ipvsadm -E改调度算法的时候,-s参数后面到底能填哪些值?我想看看当前内核编译了哪些算法,这时候有几种办法:
方法一,直接看模块加载情况:
bash复制lsmod | grep ip_vs
如果某个调度算法对应的模块没有被加载,比如ip_vs_sh,那你用-s sh就会提示不支持。常见的算法模块名如下表:
| 模块名 | 对应算法 | 说明 |
|---|---|---|
| ip_vs_rr | rr | 轮询 |
| ip_vs_wrr | wrr | 加权轮询 |
| ip_vs_lc | lc | 最少连接 |
| ip_vs_wlc | wlc | 加权最少连接(默认) |
| ip_vs_lblc | lblc | 基于局部性的最少连接 |
| ip_vs_lblcr | lblcr | 带复制的基于局部性最少连接 |
| ip_vs_dh | dh | 目的地址哈希 |
| ip_vs_sh | sh | 源地址哈希 |
| ip_vs_sed | sed | 最短期望延迟 |
| ip_vs_nq | nq | 永不排队 |
| ip_vs_fo | fo | 加权故障转移(也有资料叫Fixed Overload) |
| ip_vs_ovf | ovf | overflow,基于连接上限的加权最少连接 |
方法二,确认内核编译配置:
bash复制grep -E "CONFIG_IP_VS_RR|CONFIG_IP_VS_WRR|CONFIG_IP_VS_SH" /boot/config-$(uname -r)
如果看到=m表示编译为模块,=y表示直接编进了内核。CentOS和Ubuntu默认基本都全,但精简过的系统不一定,遇到“Scheduler not supported”这种报错,多半就是模块缺失。
方法三,看/proc/net/ip_vs:
bash复制cat /proc/net/ip_vs
这个文件里除了能确认当前每个Virtual Service用的Scheduler,还能看到TCP、UDP的超时设置,以及FWM防火墙标记的调度情况。
1.3 修改调度算法前必须知道的“平滑切换”前提
临时改算法用ipvsadm -E:
bash复制ipvsadm -E -t 192.168.1.100:80 -s wlc
改动基本是即时生效的,不会中断现有连接,但这里有个很容易忽略的坑:新建连接会按新算法分配,已经建立的连接不会重新调度。也就是说,如果从rr切到wlc,原有的长连接还是留在原来的RS上,要等它们自然断开,新调度策略才会完全接管流量。这对HTTP短连接场景问题不大,但对WebSocket、数据库连接池这类长连接场景,切换算法后的“余温期”可能持续很久。
所以我的习惯是:算法调整尽量放在业务低峰期执行,并且改完后观察ActiveConn的变化曲线,至少要等一个完整的连接生命周期(短连接场景几分钟,长连接场景几小时)再做结论。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 静态调度算法逐个拆解:RR、WRR、SH、DH
所谓静态算法,就是调度器在做选择时不考虑后端RS当前的连接数、负载情况,只看预先设定好的规则。这类算法实现简单、性能开销小,但“不聪明”。
2.1 RR(Round Robin):最朴素的轮流分配
RR就是把新的请求按顺序轮流分给每一台RS,1、2、3、4、1、2、3、4这样转圈。它只要求有轮询动作,不考虑RS的配置差异和当前压力。
它最适合的场景是:后端RS的硬件配置完全一致,上面跑的也是无状态服务,并且每个请求的处理耗时都差不多。比如一组规格相同的Nginx做静态资源服务,请求基本是“读个文件就返回”,这种情况RR的表现非常好,调度开销几乎为零。
但如果你把RR用在两台配置差异明显的机器上,比如一台8核16G、一台4核8G,那8核机器很快就会被慢机器拖累,因为分配比例是1:1,慢机器处理不过来,请求就会排队,用户体验直接恶化。
2.2 WRR(Weighted Round Robin):靠权重解决配置差异
WRR是对RR的加权改造。每台RS设置一个Weight,调度器按照权重比例来分配连接,权重越高,被选中的次数越多。比如三台RS权重分别是1、2、3,那么在6个新连接里大约会分配1、2、3个。
WRR在生产中的核心价值在于:它允许你在不改变物理拓扑的情况下,对异构集群做流量比例的精细控制。比如新上线的机器先给低权重,观察一段时间没问题再逐步放大;或者某台旧机器即将下架,把权重调低,让它慢慢“凉下来”。
权重怎么定?我的经验是第一版直接按CPU核数比例来,比如4核、8核、16核就配1、2、4。但注意这只是一个起点,最终要以实际压测数据为准。如果服务是CPU密集型,按核数配没问题;如果是IO密集型(数据库、缓存),内存和磁盘性能的影响更大,权重就要相应调整。
实操中还有一个细节:wrr的分配并不是严格的“每N个请求里按比例均匀穿插”,比如权重1和2,实际序列可能是1、2、2、1、2、2这样。这不代表算法有bug,而是内核为了减少开销采用的平滑调度策略,只要长期统计比例是对的就行。
2.3 SH(Source Hashing):把同一个客户永远送到同一台机器
SH算法会对客户端IP做哈希计算,然后把哈希值对应到某一台RS。效果是:来自同一个源IP的请求,会被稳定地调度到同一台后端机器。
它最大的价值是实现四层层面的会话保持。比如后端是Tomcat应用,又没有配置Session共享(Redis会话集中管理),你又不希望用户每次刷新页面都跳到另一台机器导致登录态丢失,那用SH就非常合适。只要源IP不变,调度器会把该用户的所有请求都打到同一台RS上。
但SH有一个极其明显的短板:哈希分布不均匀。如果某个公司出口是一个NAT网关,几千个员工都从一个源IP出去,那这些人的流量会被全部压到同一台RS上;如果恰好是个大客户,这台机器直接被打爆,而其他机器很闲。这种情况我用“雪崩起点”来形容,因为这台热点机器一旦宕机,SH会把它负责的那部分哈希空间重新分配,又可能造成新的热点。
所以SH我只建议在这种场景用:后端是有状态服务、必须保持Session,且用户IP分布足够分散(比如C端家庭宽带用户)。如果用户集中在少数几个企业出口IP,宁可改用“WLC+短持久时间”的组合,也不要用SH。
2.4 DH(Destination Hashing):面向目标地址的亲和调度
DH和SH原理类似,只是哈希对象从源IP换成了目标IP(对于四层负载均衡来说,通常就是VIP或者后端服务的目的地址)。如果是基于FWM和端口映射的场景,DH可以做到把对某个目标地址的请求固定发到某台后端。
它最典型的使用场景是代理后端缓存/反向代理集群。举个例子:你有两个目标服务地址,A服务的缓存数据存在RS1上,B服务的缓存数据存在RS2上,用DH能让对A的请求总是到RS1,尽量提升缓存命中率,减少跨节点缓存同步的开销。
不过实话实说,四层场景里正经把DH用在生产的人不多,更多人是靠七层负载均衡(如Nginx、HAProxy的URL Hash)来做内容亲和。DH的应用面比较窄,了解即可。
3. 动态调度算法逐个拆解:LC、WLC、SED、NQ、LBLC、LBLCR
动态算法的核心特征是:调度器在选择RS时,会去读取当前每台RS的连接数或某些实时状态,再结合权重做出决策。它能自适应后端压力的变化,是生产中真正的主力。
3.1 LC(Least-Connection)与 WLC(Weighted Least-Connection)
LC的思想非常直觉:谁的当前连接数最少,新请求就给谁。它假设连接数能大致反映机器负载——连接多说明忙,连接少说明闲。
WLC在此基础上加入了权重,选择标准从“最小连接数”变成“连接数/权重最小”。这个改动很重要,因为如果不考虑权重,一台4核机器和一台16核机器同样维持在100个连接,显然16核机器还远没到瓶颈,但LC会继续给4核机器派活。WLC用公式来刻画“我应该分配到多少连接才是合理的”:
code复制
选择标准:min(ActiveConn_i / Weight_i)
其中ActiveConn_i是第i台RS的活跃连接数,Weight_i是它的权重。
WLC是LVS的默认调度算法,也是我80%场景下的第一选择。它既考虑了后端当前的真实压力,又兼容了异构机器的能力差异,属于“默认不会出大错”的方案。
但WLC也有一个已知的坑,我后面单独用一节来讲——短连接快速建立又释放的场景下,连接数统计可能严重滞后,反而导致倾斜。
3.2 SED(Shortest Expected Delay):从排队论里来的调度策略
SED的全称是Shortest Expected Delay,中文一般翻译成“最短期望延迟”。它的选择标准是:
code复制
选择标准:min((ActiveConn_i + 1) / Weight_i)
这个公式的意思是:如果我把一个新连接分给第i台RS,这台机器上每个连接“平均分摊到的权重负担”会变成(ActiveConn_i + 1) / Weight_i。调度器选择这个值最小的机器,相当于预估“我这个新连接到这台机器之后,它处理我的速度最快”。
SED和WLC的区别在于:WLC看的是“当前状态”,SED看的是“把我加进去之后的状态”。举个例子,假设有两台机器,权重都是1,A机器当前有3个连接,B机器有0个连接:
- WLC:min(3/1, 0/1),选B。
- SED:min((3+1)/1, (0+1)/1),选B。
看起来两者一样,但换一种情况:A机器权重10,当前30个连接;B机器权重1,当前1个连接。
- WLC:min(30/10=3, 1/1=1),选B。
- SED:min((30+1)/10=3.1, (1+1)/1=2),还是选B。
你会发现SED比WLC更“看重权重”。它在后端响应时间差异比较大的场景下表现更好,尤其适合那些每个连接处理时间不固定的服务,比如API网关。但SED也有个副作用:如果所有RS的连接数都不少,它倾向于把请求堆到权重最大的机器上,从而可能让高权重机器的负载偏大,需要留意观察。
3.3 NQ(Never Queue):不让请求排队,宁可直接分配
NQ是SED的一个改进变种。它有一个规则:如果当前所有RS的连接数都为0,就简单地用轮询或者直接顺序分配,而不是再做计算;只有当所有RS都有连接存在时,才按SED的公式去选择。
这个设计解决了一个典型问题:在一批全新启动的RS上,服务器刚开机时连接数全是0,SED会一直选第一台机器,直到它有了第一个连接,然后才轮到第二台。如果你有100台机器刚一起启动,第一台机器可能瞬间被塞进大量请求,而其他99台都闲着。NQ通过“全空闲时就轮询分配”,避免了这种空转瞬间的打爆。
实际场景里,NQ更适合Conntrack状态重置、RS批量重启后的流量恢复期。不过它也不是银弹,空闲判定只是看连接数为0,如果一台机器虽然连接数为0但是CPU已经打满了(比如在处理密集型任务),NQ还是会把请求分给它。
3.4 LBLC 与 LBLCR:为Cache集群打造的局部性算法
LBLC(Locality-Based Least-Connection)可以理解为“DH+LC”的融合:对于来自同一目的IP的请求,它会尽量调度到上次处理该目的IP的那台RS,但如果那台RS已经过载(连接数超标),则会将请求调度到连接数最少的RS。
LBLCR(Locality-Based Least-Connection with Replication)更进一步:它允许同一个目的IP的内容缓存副本存在多台RS上,调度器会维护一个“目的IP->RS集合”的映射。当目标RS过载时,它不只切换到连接数最少的机器,还会把这个新机器加入目标IP的缓存副本集合。后续再有相同目的IP的请求,会优先在这些已缓存副本的RS之间做最小连接选择。
这两兄弟就是专门给缓存服务集群准备的,典型场景是“一堆后端Squid/Varnish做HTTP缓存”。用LBLC/LBLCR的优势是:同一个URL的请求尽量被送到缓存了该内容的机器上,命中率显著提升,同时因为有多副本(LBLCR),又不会像DH那样把热点请求钉死在一台机器上。
不过这俩算法在内核里是实验级偏保守的存在,稳定性和生态都不如WLC成熟。我自己的建议是:如果不是明确做四层Cache转发,就不用碰它们;缓存亲和用七层负载均衡的URL Hash做起来更顺手、更容易观测。
4. 生产环境的算法选型:场景对照与平滑切换实践
4.1 一张速查表解决日常80%的选型问题
我把LVS各个调度算法适合的业务场景整理成了一张表,运维同学可以直接贴在wiki里备用:
| 业务场景 | 推荐算法 | 原因 |
|---|---|---|
| 无状态Web服务,RS配置完全一致 | RR | 最简单、开销最小、分布绝对均匀 |
| 无状态Web服务,RS配置不一致 | WRR | 按权重分配,符合机器能力比 |
| 常规HTTP/API服务,配置不一,要兼顾实时负载 | WLC | 默认算法,自适应后端压力,最通用 |
| 长连接服务(数据库中间层、WebSocket、IM) | WLC 或 SED | 连接数能较好反映长连接后端压力 |
| 后端响应时间差异明显 | SED | 公式会权衡“新增连接带来的延迟预期” |
| RS会批量重启、需要平滑恢复流量 | NQ | 避免空闲机器被连续打满 |
| 强Session保持,用户IP分布分散 | SH | 同源IP固定到同一台RS |
| 缓存集群,追求URL/目的地址亲和 | DH 或 LBLC/LBLCR | 尽量让相同目的IP的请求命中同一后端缓存 |
| 新旧RS灰度切换 | WRR(权重从0渐变) | 权重可以细粒度控制流量比例 |
这个表不是我拍脑袋写的,都是基于生产环境反复验证过的结论。尤其是“灰色地带”的场景——比如既要求Session保持又希望负载均衡,不要焦虑,答案不是非黑即白,可以用持久性参数配合动态算法来实现,这是下一节要讲的。
4.2 实操:从RR切换到WLC并验证效果
假设当前VIP是192.168.1.100:80,三台RS分别是11、12、13,权重分别为1、2、3,当前算法是RR。我们想切到WLC,完整流程如下:
bash复制# 第一步:确认当前状态
ipvsadm -L -n --stats
# 第二步:切换调度算法(-E 编辑已存在的virtual service)
ipvsadm -E -t 192.168.1.100:80 -s wlc
# 第三步:确认切换成功
ipvsadm -L -n
# 第四步:如果发现某个RS权重不对,临时调整
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.12:80 -g -w 3
# 第五步:观察速率和连接分布
ipvsadm -L -n --rate
ipvsadm -L -n --stats
有几个要点值得提醒:
-a是添加RS,如果你只是想改已有RS的权重,也可以用ipvsadm -a配合相同参数来覆盖更新(内核会按相同地址复用)。不过更稳妥的写法是对已有RS执行ipvsadm -a -t ... -r ... -w 新权重,这在一部分发行版上是允许的,但如果你想完全遵守“新增/修改分离”的原则,建议用ipvsadm -E -t ... -s ...改算法、用ipvsadm -a -t ... -r ... -w ...设置权重。- 切换算法后,至少观察10分钟到半小时的
ActiveConn曲线。如果某台RS的ActiveConn突然一直爬升,要立刻回滚到原算法。 - 别忘了看
--rate里的CPS,有些负载均衡的坑不在连接数分布,而在每秒新建连接数不均匀。
4.3 持久性参数和调度算法的联动:一个被忽略的关键点
LVS的-p参数(持久性,persistence)能改变调度算法的实际行为。设置了持久性后,来自同一来源IP的连接,在一个时间段内会被强制送到同一台RS上,而这个“绑定”优先于调度算法。
举个例子:你用的是wlc算法,本意是让新连接按连接数比例分配,但如果你同时设置了ipvsadm -E -t 192.168.1.100:80 -s wlc -p 600,那么同一个IP在600秒内所有的连接都被固定到同一台机器上。这时候wlc只能在“新的源IP第一次进来”时发挥作用,跟sh的表现非常像。
那个坑就在这:如果你对持久性机制不熟悉,很可能会发现“为什么我改了权重、改了算法,连接分布还是不变”。排查步骤应该先看Flags列,那里如果有persistent标识,就要清楚持久性的存在。
我一般这样搭配:
| 需求 | 推荐组合 |
|---|---|
| 普通无状态业务,最均匀分布 | 不设置持久性 + WRR/WLC |
| 希望Session保持,又不像SH那样死板 | WLC + -p 120(120秒持久) |
| 花在网络层做连接会话保持的支付类接口 | SH,或者 WLC + -p 3600 |
这里特别说一句:-p时间别贪长。很多团队把持久时间设成一小时、一天,结果是高峰期某个客户流量全堆在一台机器上,其他机器空闲。持久性只应该覆盖“一次会话的正常生命周期”,比如HTTP接口通常120秒、300秒足够,过度持久和SH的热点问题没有本质区别。
5. 我在生产环境踩过的调度算法坑与排查手记
5.1 案例一:WLC下新连接全部涌向一台新上线的服务器
有一次我把一台新RS加入LVS集群,结果流量不是平滑铺开,而是瞬间涌向新机器,老机器反而空闲。起初还以为wrr配置错了,一查才发现用的是WLC。
原因其实不复杂:新RS刚刚加入,ActiveConn和InActConn都从0开始,而老机器经过一整天运行,连接数积累到了几百上千。WLC按“连接数/权重”取最小,新RS的比例值接近0,自然每个新连接都被分到它头上,直到它的连接数长起来,分布才慢慢趋于均衡。
这个现象在短连接服务上尤其明显,因为短连接建立快、释放也快,但ActiveConn采样统计有延迟,新机器会持续被“喂”到连接数足够高。结果就是新机器那几小时CPU飙高、load拉满,老机器却很闲。
解决办法:
- 新机器加入时,初始权重不要照搬目标权重,先设一个低权重(比如正常权重的1/5),再逐步调上来。
- 如果已经发生了倾斜,最快的干预方式是临时把其他机器的连接数“预热”起来——可以通过压测工具给它们发送一批请求,也可以直接短暂把新机器权重改成0,让连接数统计回归理性。
- 更彻底的做法是监控
ActiveConn和InActConn的实时曲线,加入告警:当某台RS的ActiveConn低于平均值30%以上且持续5分钟,触发人工检查。
5.2 案例二:SH算法在企业出口NAT环境中的灾难现场
有个朋友的公司给内部员工搭了一套办公系统,后端几台Tomcat,为了保持登录态,用了SH算法。刚开始很顺畅,但一到下午全员在线,某台服务器直接假死,其他机器负载可怜。
排查后确认问题不在后端代码,而是他们的办公网是大型NAT出口,所有员工最终到达LVS的源IP只有三五个。SH根据源IP哈希,等于这几千号人的流量永远只落在两三台机器上。这就是我前面说过的“热点倾斜”典型现场。
处理方案有两条路线:
- 短期:切到
wlc + -p 300,这样既能在5分钟维度内保持会话(用户刷新页面不会掉登录态),又能让不同源IP的请求在整体负载上铺开。这个方案我当时直接用了,效果立竿见影。 - 长期:如果业务实在需要强会话保持,就引入应用层的Session共享,把Tomcat的Session放到Redis里,然后大胆用
wrr或者wlc,彻底摆脱对客户端IP的依赖。
5.3 案例三:ipvsadm -L -n显示权重正确,但流量分配明显不对
这个案例更隐蔽。某天有同事反馈:明明三台RS权重是1:1:1,但在监控上看流量差距很大,确定已经切到了wrr。我上去查,ipvsadm -L -n显示的Weight确实都是1,看起来一切正常。
后来才发现,问题出在连接持久性上。原来这个VIP在很久以前被配置过-p 3600,当天恰好有大量源IP是公司内部NAT出口,这些IP被持久性绑定到了特定RS上,所以在持久时间窗口内,即使wrr按照权重分配新连接,也架不住这些“大头IP”根本不参与轮询。持久性会截胡调度算法,这个现象后面我们叫它“幽灵绑定”。
处理方式是:移除持久性设置,或者重新设置合理的持久时间。命令:
bash复制# 把flags清掉,注意重新编辑VIP时不能只填-s,也会影响flags
ipvsadm -E -t 192.168.1.100:80 -s wrr
在-E时如果没有指定-p,持久性就会被重置为0,这样那些旧的源IP绑定关系也会清掉。
5.4 案例四:--timeout和调度算法一起导致TIME_WAIT堆积
最后说一个和调度算法看似无关、但经常一起被误判的配置——超时时间。LVS内核里有三种超时:TCP空闲超时(默认900秒)、TCP FIN等待超时(默认120秒)、UDP超时(默认300秒)。
如果后端是短连接业务,前端大量请求快速建立并关闭,而你的TCP TIME_WAIT状态连接因为持久性或者fin超时配置过长,会一直挂在InActConn里。在WLC的计算中,InActConn虽然不参与ActiveConn的权重计算,但它会占据RS的内存和连接表,导致该机整体性能下降,进而间接影响调度器的“健康”判断。
所以调优调度算法时,一定要一起检查:
bash复制ipvsadm -L -n --timeout
我个人会结合实际业务的连接模型,把TCP空闲超时从900秒适当调短到300-600秒,加快连接表回收,这在内网高并发短连接场景下能明显减少内存占用。
6. 写给刚接手LVS集群的人:三个低成本验证方法
6.1 用curl反复请求验证算法分布
如果你只是想验证某台VIP当前的调度策略,最朴素的方法就是开几个终端循环发请求:
bash复制for i in $(seq 1 100); do curl -s http://192.168.1.100/ | grep -o "server-1[1-3]"; done | sort | uniq -c
后端RS上如果返回的页面带机器标识,你能很快看到100次请求的分布比例。注意得把浏览器缓存和本地DNS去掉,尽量保证每次都是新连接。
6.2 用ipvsadm --rate观察每秒新建连接是否均匀
ipvsadm -L -n --rate实时输出每秒钟的新建连接数(CPS),观察几轮:
bash复制ipvsadm -L -n --rate
如果某台RS的CPS明显高于其他RS,而权重比例又没这么大,优先查一下是不是持久性设置、源IP哈希导致的热点问题。
6.3 用conntrack或ss核对真实连接归属
有时候ipvsadm统计和实际socket状态对不上,因为LVS是工作在内核的,统计也可能受到连接表老化策略影响。更准确的检查方法是直接在某台后端RS上看有没有来自VIP的流量连接:
bash复制ss -ant | grep 192.168.1.100 | wc -l
把三台RS的实际ESTABLISHED连接数算出来,再对比ipvsadm -L -n --stats里的ActiveConn,基本就能定位是统计问题还是调度问题。
做了这么多踩坑和验证,我最深的感受是:LVS的调度算法不是“选一个就万事大吉”,它是一个需要根据业务连接模型、机器配置差异、会话保持需求不断微调的动态参数。建议每个集群都记录一份调度算法变更日志,写明哪天、因为什么原因、从什么算法切到什么算法、观察指标是什么、结果如何。这套记录帮我在半年内积累了足够的选型样本,之后再碰新业务,基本看一眼架构就能给出合理建议。
