一. LVS的调度算法
1.1 调度算法的内容与类型
- IPVS(IP Virtual Server)是 Linux 内核中实现负载均衡的核心模块,而 IPVS Scheduler 则是 IPVS 的调度器,负责将客户端请求分发到后端真实服务器(RS)。是 LVS技术的核心组件,支持多种调度算法,可根据不同场景优化负载均衡效果。
- IPVS Scheduler 的调度算法主要分为静态算法 和动态算法两类
1.2 LVS静态调度算法
静态算法**:**仅根据算法自身的规则进行调度,不考虑 RS 的实时负载情况(如连接数、CPU 使用率等),适用于各RS性能相近且负载波动较小的场景。主要包括以下四种:
- RR(Round Robin,轮询)
- 原理:将客户端请求按顺序轮流分配给后端的每个 RS,每个 RS 被调度的次数均等。
- 特点:实现简单,但未考虑 RS 的性能差异。若各 RS 配置(如 CPU、内存)不同,性能较差的 RS 可能因频繁被调度而过载。
- WRR(Weighted Round Robin,加权轮询)
- 原理:为每个 RS 分配一个权重(weight),权重越高的 RS 被调度的次数越多。
- 特点:解决了 RR 算法中 "忽略 RS 性能差异" 的问题,性能较差的 RS 可通过设置低权重减少被调度次数,适用于 RS 性能有差异的场景。
- SH(Source Hashing,源地址哈希)
- 原理:根据客户端的源 IP 地址进行哈希计算,将来自同一源 IP 的请求始终分配给第一次选中的 RS,实现 会话绑定(Session Sticky)。
- 特点:保证同一客户端的请求持续发送到同一 RS,适用于需要维持会话状态的场景(如用户登录后的操作),但可能导致部分 RS 因特定 IP 的高频请求而过载。
- DH(Destination Hashing,目标地址哈希)
- 原理:根据请求的目标 IP 地址(如用户访问的域名对应的 IP)进行哈希计算,第一次通过轮询选择 RS,后续同一目标 IP 的请求始终分配给该 RS。
- 特点:可将同一目标地址的请求集中到同一 RS,提高缓存命中率,避免重复缓存相同内容。
1.3 LVS动态算法
动态算法:调度时会结合各 RS 的实时负载状态(如活动连接数、非活动连接数等)和算法规则,优先选择负载较低的 RS。其核心是通过计算 "负载值(Overhead)" 判断 RS 的繁忙程度,Overhead值越小的RS将被优先调度。主要包括以下六种:
- LC(Least Connections,最少连接)
- 原理:优先选择当前连接数最少的 RS,连接数通过 活动连接数(activeconns) 和 非活动连接数(inactiveconns)计算,Overhead = activeconns x 256 + inactiveconns。
- 特点:适用于长连接应用(如数据库连接、WebSocket),可避免 RS 因连接数过多而过载,但未考虑 RS 的性能差异。
- WLC(Weighted Least Connections,加权最少连接)
- 原理:在 LC 算法基础上引入权重,Overhead = (activeconns x 256 + inactiveconns ) / weight 。权重越高的 RS,相同连接数下的 Overhead 值越小,被调度的优先级越高。
- 特点:是LVS的默认调度算法,兼顾连接数和 RS 性能,既避免连接数过多的 RS 过载,又让高性能RS承担更多请求,适用场景最广泛。
- SED(Shortest Expectation Delay,最短预期延迟)
- 原理:优化 WLC 算法对新 RS 的调度策略,Overhead = (activeconns + 1 + inactiveconns ) x 256 / weight 。
- 特点:初始阶段会优先调度高权重的 RS。例如:RS1 权重为 1、RS2 权重为 10 时,前几次请求会优先分配给 RS2,快速让高权重 RS 承担更多负载,适用于需要高权重 RS 优先处理请求的场景。
- NQ(Never Queue,永不排队)
- 原理:第一轮请求按轮询方式均匀分配给各 RS(确保每个 RS 至少处理一个请求),从第二轮开始采用 SED 算法调度。
- 特点:避免新启动的 RS 因初始连接数为 0 而被 SED 算法过度优先调度,同时防止某一 RS 长期空闲,适用于希望各 RS 初期负载更均衡的场景。
- LBLC(Locality-Based Least Connections,基于局部性的最少连接)
- 原理:动态版的 DH 算法,结合目标地址哈希和最少连接策略。对于新的目标地址请求,先按最少连接原则分配 RS;后续同一目标地址的请求优先分配给该 RS,若该 RS 负载过高,则重新选择负载较低的 RS。
- 特点:正向代理服务器的负载均衡(如 CDN 节点),既保证同一目标地址的请求集中处理以提高缓存效率,又避免单 RS 过载。
- LBLCR(LBLC with Replication,带复制功能的 LBLC)
- 原理:在 LBLC 基础上增加 "复制" 机制。当某一目标地址的请求集中导致对应 RS 负载过高时,会将该目标地址 "复制" 到其他负载较低的 RS,新请求可分配给这些复制节点。
- 特点:解决了 LBLC 中因目标地址集中导致的单 RS 过载问题,进一步提高负载均衡的合理性,适用于目标地址请求分布不均的场景。
1.4 在4.15版本内核以后新增调度算法
Linux内核4.15版本之后新增了两种 LVS 调度算法,主要用于特定场景的负载均衡优化。。
-
FO(Weighted Fail Over)调度算法
- 原理:遍历虚拟服务关联的真实服务器(RS)链表,选择未过载(未设置IP_VS_DEST_F OVERLOAD标志)且权重最高的 RS 进行调度。管理员可通过ipvsadm命令手动标记 RS 为过载,使其暂时不接收新连接。
- 特点:FO 算法专为灰度发布设计,通过权重灵活控制流量比例,支持无损切换(标记过载后已建立连接不受影响),但依赖管理员主动监控和干预,适合需要精确控制流量切换的场景。
-
OVF(Overflow-connection)调度算法
- 原理:遍历 RS 链表,选择未过载、活动连接数小于权重值且权重不为 0 的 RS 进行调度,每个 RS 的权重值同时作为连接数阈值,达到阈值时自动切换至下一台 RS。
- 特点:OVF 算法通过权重值实现连接数的精确控制,无需手动标记即可自动规避过载风险,但需要根据 RS 性能测试结果精细配置权重,适合对连接数敏感、需严格防止服务器过载的场景。
二. 火墙标记解决多端口轮询错误
2.1 可能遇到的错误
以http和https为例,当我们在RS中同时开放80和443端口,那么默认控制是分开轮询的,这样我们就出 现了一个轮询错乱的问题
-
在RS1与RS2上安装mod_ssl并重启apache
RS1
[root@RS1 ~]# dnf install mod_ssl -y
[root@RS1 ~]# systemctl restart httpdRS2
[root@RS2 ~]# dnf install mod_ssl -y
[root@RS2 ~]# systemctl restart httpd -
查看端口,有80和443两个端口

- 在lvs-dr中设置调度,因为要调度80和443两个端口所以我们需要设定两组策略



- router无法访问,lvs-dr需要关闭火墙


2.2 防火墙标记解决轮询调度问题
MARK target 可用于给特定的报文打标记,--set-mark value
其中 value 可为0xffff格式,表示十六进制数字借助于防火墙标记来分类报文,而后基于标记定义集群服务:可将多个不同的应用使用同一个集群服务进行调度
- 在lvs-dr主机上打标记


三. session会话保持优化方案
3.1 持久连接的需求背景
用户在上网与服务器交互的过程中,进行提交表单等操作,若仅采用常规调度算法,每次请求都可能被随机分配到不同的后端真实服务器。这可能导致用户之前填写的数据丢失,影响用户体验。早期为了解决这个问题,我们会使用sh算法,但是sh算法简单粗暴,可能会导致调度失衡。
3**.2 优化方案**
-
记录调度信息:当客户端的数据包到达 LVS 调度器时,只要是相同源 IP 的请求,调度器就会将该源 IP 的请求被调度到的 RS 信息记录在内存中。
-
短期会话保持:在默认360秒的短期时间内,如果同一个源 IP 再次发起访问请求,LVS 调度器会依据内存中记录的调度信息,将请求仍然调度到之前的那台 RS 上,确保用户的会话状态得以维持,不会出现数据丢失或操作中断的问题。
-
长期会话重新调度:当超过默认最长时间 360 秒后,若该源 IP 再次访问,此时 LVS 调度器不会再沿用之前的记录,而是将其作为新的请求,按照当前所使用的调度算法(如轮询 RR、加权最少连接 WLC 等)重新进行调度,分配到其他合适的 RS 上,以避免某一台 RS 长期承载同一客户端的大量请求而出现负载不均衡。
设置相关参数命令
ipvsadm -AlE -tlulf service-address [-s scheduler] [-p [timeout]]
-A :添加虚拟服务器; -l :列出虚拟服务器;
-E :编辑虚拟服务器; -t :指定 TCP 协议的虚拟服务器;
-u :指定 UDP 协议的虚拟服务器 -l :使用长格式输出;
-f :指定虚拟服务的防火墙标记 -s :指定调度算法;
-p :启用持久连接,并可指定超时时间(单位为秒),若不指定则默认 360 秒 。
