Files

144 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [test/review, architecture, arch/microservice, rate-limiting]
create time: 2026-08-09 12:00
---
# 限流熔断降级 — 测试题
## 概述
本测试覆盖三种限流算法(滑动窗口、令牌桶、漏桶)、熔断三态转换机制、Sentinel 与 Resilience4j 核心特性以及降级兜底策略。共 10 道题目(6 选择 + 3 填空 + 1 简答)。
---
## 一、选择题(6道,由浅入深)
> **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
### Q1(基础)— 考察定义层面
以下哪种限流算法**不允许突发流量**,强制输出匀速?
A. 计数器限流
B. 令牌桶算法
C. 漏桶算法
D. 以上都不对
### Q2(基础)→
熔断器从 Closed 状态转换到 Open 状态的典型触发条件是什么?
A. 单个请求失败
B. 最近 N 秒内成功率为零
C. 失败率超过阈值(如 >50%)
D. HPA 检测到 CPU 使用率过高
### Q3(进阶)— 核心原理
熔断半开(HalfOpen)状态的主要作用是什么?
A. 降低服务器负载,减少请求量
B. 用少量探测请求验证下游是否已恢复,避免直接进入 Closed 后流量暴增导致二次雪崩
C. 为客户端提供缓冲时间,等待前端超时
D. 在 Open 和 Closed 之间做数据同步
### Q4(进阶)— 比较/辨析
Resilience4j 与 Hystrix 的核心区别不包括以下哪项?
A. Resilience4j 基于信号量隔离(轻),Hystrix 基于线程池隔离(重)
B. Resilience4j 采用函数式设计,Hystrix 需要继承 Thread
C. Resilience4j 不依赖 Spring Cloud,可以独立使用
D. Resilience4j 不支持熔断功能
### Q5(深入)— 场景推理
某 API 网关需要对用户接口做限流保护。业务要求允许合理的突发流量(如用户刷新页面同时发多个请求),但限制长期平均速率。以下选型最合理的是:
A. 漏桶——因为保护消费者不被打爆
B. 令牌桶——因为允许突发消费存量令牌
C. 固定窗口计数器——因为实现最简单
D. 并发线程数限流——因为实现最轻量
### Q6(深入)— 源码级/边界场景
Sentinel 的滑动窗口与传统固定窗口的核心区别是什么?
A. Sentinel 使用 Redis 做分布式计数,传统方式用本地内存
B. Sentinel 将窗口细分为更小的 tick,在每个 tick 内独立计数再聚合;固定窗口在边界处会漏算(上一个窗口的尾巴 + 下一个窗口的头同时超限)
C. Sentinel 支持更多算法(令牌桶+漏桶+计数器),传统方式只支持计数器
D. Sentinel 不需要配置阈值,通过自适应学习自动设定
---
## 二、填空题(3道)
### F1 — 填空1
HPA(Horizontal Pod Autoscaler)的计算公式是:`targetReplicas = ceil(currentReplicas * (currentMetricValue / _____))`。例如当前 5 个副本,CPU 目标 70%,当前平均 CPU 使用率 91%,则扩容到 `ceil(5 * 91 / 70) = _____` 个副本。
> **提示**: 第一个空填公式中的占位符名,第二个空填计算结果。
### F2 — 填空2
Prometheus 采集指标使用 Pull 模式而非 Push 模式的原因是:Pull 模式下失联的服务会自动被忽略(不再收到数据即标记为 down),而 Push 模式下挂了的服务停止发送数据但采集器不知道它们已经不存在了。请写出 Prometheus 中四种核心指标类型中的两种:_____、_____。
> **提示**: 任选两种即可——Counter/Gauge/Histogram/Summary。
### F3 — 填空3
Token Bucket 和 Leaky Bucket 的选型建议:**对外暴露 API 时用_____**(允许客户端合理突发);**内部服务间调用时用_____**(保护消费方不被打爆)。
> **提示**: 每个空填一种算法名称。
---
## 三、简答题(1道)
### S1
面试官问:"为什么熔断要从 Open 到 HalfOpen 而不是直接从 Open 回到 Closed?"请详细解释原因,并结合以下场景说明后果:某个下游微服务的数据库连接池被打满,故障正在恢复中。
> **答题框架提示**:
> 1. HalfOpen 的安全阀作用
> 2. 直接回 Closed 的后果分析
> 3. HalfOpen 探测的具体流程
> 4. 补充:如果 HalfOpen 也失败的策略
---
## 参考答案与解析
### 选择题答案
| 题号 | 正确答案 | 解析 |
|------|---------|------|
| Q1 | C | 漏桶的核心就是无论输入多猛,输出永远匀速——请求进入桶中排队处理,满了就溢出拒绝。令牌桶允许突发(桶满时可以一次性消耗多个令牌),计数器有窗口边界问题。 |
| Q2 | C | 典型触发条件是失败率超过阈值(如最近 N 秒内失败率 > 50%)。单个请求失败不够成熔断,全为零太极端。 |
| Q3 | B | HalfOpen 是一个安全阀:下游还在恢复时,直接进入 Closed 会让全部流量瞬间灌入,可能导致二次雪崩。有限的探测请求(通常 1~3 个)先验证下游是否真恢复了。 |
| Q4 | D | D 是错误的——Resilience4j **完全支持**熔断功能。它的优势在于函数式 API 和装饰器模式。其他三项都是正确的区别点。 |
| Q5 | B | 令牌桶适合保护生产者:允许突发流量(桶满时可突发消费存量令牌),但长期受限于平均速率。这正是对外 API 网关的需求特征。 |
| Q6 | B | 固定窗口的问题在于边界效应:上一个窗口末尾 0.9 秒的请求和下一个窗口开头 0.9 秒的请求各占各自窗口但不超出阈值,合在一起可能翻倍。Sentinel 将窗口细分为更小的 tick 来消除这个问题。 |
### 填空题答案
| 题号 | 答案 | 解析 |
|------|------|------|
| F1 | `desiredMetricValue`;`7` | ceil(5 × 91 / 70) = ceil(6.5) = 7。HPA 不是实时的——依赖 metrics-server 每 15~60 秒采样,扩容有分钟级延迟。 |
| F2 | `Counter`、`Gauge`(或 Histogram、Summary 任意两种) | Counter = 单调递增(如总请求数);Gauge = 可上可下(如活跃连接数);Histogram = 分桶统计(延迟分布);Summary = 客户端计算分位数(P50/P99)。 |
| F3 | `令牌桶`;`漏桶` | 对外 API 允许合理突发 → 令牌桶;内部服务间保护消费方 → 漏桶匀速处理。 |
### 简答题参考答案
S1:**参考答案要点**:
1. **安全阀作用**:HalfOpen 是 Open 和 Closed 之间的缓冲层,用有限的探针先测试下游恢复情况。
2. **直接回 Closed 的后果**:假设下游 DB 连接池被打满(比如只剩 5 个可用),如果直接从 Open 回 Closed,大量积压请求瞬间涌入会立即再次打满连接池,引发二次雪崩。
3. **HalfOpen 流程**:仅发出 1~3 个探测请求给下游,只有全成功才转入 Closed。任一失败立刻重新进入 Open 并重置倒计时。探测期间原有业务请求仍被拦截。
4. **补充**:如果连续多次 HalfOpen 都失败,可以引入渐进式加大探测流量的策略,或者人工介入告警。
**评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。
## 关联笔记
- [[服务注册与发现]]
- [[负载均衡算法]]
- [[配置中心设计]]