--- tags: [test/review, architecture, arch/microservice, load-balancing] create time: 2026-08-09 12:00 --- # 负载均衡算法 — 测试题 ## 概述 本测试覆盖客户端 vs 服务端负载均衡架构、轮询/随机/一致性哈希/最少连接等核心算法、Spring Cloud LoadBalancer 实现原理以及加权轮询的工程实现。共 10 道题目(6 选择 + 3 填空 + 1 简答)。 --- ## 一、选择题(6道,由浅入深) > **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景 ### Q1(基础)— 考察定义层面 以下关于客户端负载均衡与服务端负载均衡的说法中,正确的是: A. 客户端负载均衡延迟更高,因为多了一次网络跳 B. 服务端负载均衡的故障隔离更好——LB 单点故障不影响其他调用 C. 客户端负载均衡需要为每种语言实现 SDK,服务端 LB 协议无关 D. Nginx 是客户端负载均衡的典型代表 ### Q2(基础)→ 以下哪种负载均衡算法最适合 WebSocket 长连接场景? A. 简单轮询(Round Robin) B. 随机法 C. 最少连接数(Least Connections) D. 一致性哈希 ### Q3(进阶)— 核心原理 传统哈希 `hash(instance) % n` 在实例增减时为什么会导致大量请求重新路由? A. 因为 hash 函数的不均匀性 B. 因为 n 变化后所有 hash 结果对新的 n 取模都变了 C. 因为虚拟节点数量不足 D. 因为 MurmurHash 本身不适合负载均衡 ### Q4(进阶)— 比较/辨析 一致性哈希中虚拟节点的主要作用是什么? A. 提高 hash 值的随机性 B. 解决数据倾斜问题,使物理实例在环上分布更均匀 C. 增加系统容错能力,某节点挂了可以立即接替 D. 减少 hash 冲突的概率 ### Q5(深入)— 场景推理 一个微服务有 5 个实例,权重分别为 A=5、B=3、C=2、D=1、E=1(总权重 12)。使用平滑加权轮询算法,第一个被选中的实例一定是: A. B(权重 3) B. C(权重 2) C. A(权重 5) D. 无法确定,取决于初始 current_weight ### Q6(深入)— 源码级/边界场景 关于 Spring Cloud LoadBalancer,以下说法哪个是正确的? A. 它内置了重试和熔断能力 B. 基于 Reactor 响应式编程,返回 Flux C. 默认使用一致性哈希算法 D. 只支持 HTTP 协议的实例选择 --- ## 二、填空题(3道) ### F1 — 填空1 一致性哈希将 hash 值空间映射到环上(0 ~ _____),服务和请求都 hash 到环上的同一点,请求顺时针找到最近的实例。移除一个实例只影响其相邻的两个虚拟节点范围,而非全部数据。 > **提示**: 回忆原文中提到的一致性哈希环的范围上限。 ### F2 — 填空2 一致性哈希中,每个物理实例对应的虚拟节点数 k 通常取 _____~_____。如果实例频繁增删(每几分钟变一次),k 要调得更大(500+)才能维持稳定性,但会增加内存开销。 > **提示**: 原文中有一个具体的数值范围。 ### F3 — 填空3 Nginx 的 smooth weighted round robin 算法中,每次选出 current_weight 最大的实例后,执行 `selected.CurWeight -= _____`,保证长期均衡。 > **提示**: 减去的应该是总权重,这样每个实例的 CurWeight 会在一个周期内回到初始状态。 --- ## 三、简答题(1道) ### S1 某电商大促场景中,你有 10 个商品推荐服务实例,其中 3 台是高性能机器(容量大),7 台是普通机器(容量小)。流量高峰时要求充分利用高性能机器的资源。请说明你会选用哪种负载均衡算法,如何配置参数,并解释为什么不用简单轮询或随机法。 > **答题框架提示**: > 1. 分析场景的核心矛盾(规格差异) > 2. 推荐算法并说明理由 > 3. 给出具体配置思路 > 4. 讨论边界情况 --- ## 参考答案与解析 ### 选择题答案 | 题号 | 正确答案 | 解析 | |------|---------|------| | Q1 | C | A 错:客户端 LB 少一次网络跳所以延迟低;B 错:LB 单点故障影响全部请求,故障隔离差;D 错:Nginx 是服务端 LB。只有 C 正确——客户端 LB 需要各语言的 SDK(如 Spring Cloud LoadBalancer for Java)。 | | Q2 | C | WebSocket 长连接场景下不同连接的持续时间差异大,最少连接数能保证新请求发给当前活跃连接最少的实例,避免某个实例堆积大量长连接而其他实例闲置。 | | Q3 | B | 当实例数从 n 变为 n±1 时,几乎所有 key 的 hash(key) % new_n 都会不同于原来的结果,导致约 (n-1)/n 的数据需要迁移。这就是一致性哈希要解决的问题。 | | Q4 | B | 如果不使用虚拟节点,少数几个物理实例在环上的分布会很不均匀,造成严重的数据倾斜。K=100~200 个虚拟节点让分布趋近均匀。 | | Q5 | C | 平滑加权轮询第一轮时所有实例的 CurWeight = 0,加上各自 Weight 后 A 的 CurWeight = 5 最大,所以第一轮一定选 A。之后 A 减 12 变为 -7,其他依次加完再选。 | | Q6 | B | Spring Cloud LoadBalancer 基于 Reactor,返回 Flux。它**不提供**重试和熔断(那是 Resilience4j 的职责),默认策略是 RoundRobinLocator(轮询),不是哈希。 | ### 填空题答案 | 题号 | 答案 | 解析 | |------|------|------| | F1 | `2^32`(或"4294967296") | 一致性哈希将 32 位 hash 空间映射为环形地址空间,首尾相接。顺时针寻找最近实例的逻辑确保了实例增减时的最小影响范围。 | | F2 | `100`;`200` | 这是业界经验值。太少了分布不均,太多了内存占用大且维护代价高。频繁增删场景需要 500+ 的虚拟节点数。 | | F3 | `totalW`(或"总权重 total_weight") | Nginx 的平滑加权轮询核心公式:cur += weight(累积),选 max 后 selected -= total。这样经过一个完整周期,每个实例被选中的次数恰好等于它的权重占比。 | ### 简答题参考答案 S1:**参考答案要点**: 1. **核心矛盾**:性能差异大的实例不能用简单轮询——每台都会被分到相同数量的请求,导致弱机过载而强机资源浪费。 2. **推荐算法**:加权轮询(Weighted Round Robin)。将 3 台高性能机的权重设为普通机的若干倍(如 3:1 或根据实测 QPS 计算比例),使得长期来看请求按容量比例分配。 3. **不选简单的理由**:简单轮询无视容量差异;随机法在小样本下可能极端不均(连续命中同一个弱机),大促场景不能接受这种不确定性。 4. **边界处理**:需要考虑实例下线时的权重动态调整(Hot Restart 机制)、健康检查剔除故障实例后的自动重新加权。 **评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。 ## 关联笔记 - [[服务注册与发现]] - [[限流熔断降级]]