流量治理
流量治理解决微服务集群的雪崩问题。核心策略:熔断(快速失败防扩散)、限流(控制流量入口)、降级(返回兜底结果)。
提示
熔断、限流、降级的服务容错策略
雪崩效应
Service A → Service B → Service C(故障)
↓
B 请求堆积 → B 也故障 → A 请求堆积 → A 也故障根本原因:同步调用 + 无超时控制 + 无熔断保护。
超时控制和限流熔断是防雪崩的基础。
熔断器
熔断器通过三种状态保护故障扩散:
| 状态 | 行为 | 触发条件 |
|---|---|---|
| Closed | 正常请求,统计失败率 | 默认状态 |
| Open | 快速失败,返回 fallback | 失败率超过阈值(默认 50%) |
| Half-Open | 放行少量请求探测 | 熔断持续时间结束 |
Open 状态下主动拒绝请求,避免请求积压拖垮整个链路。
Sentinel vs Hystrix
| 维度 | Hystrix | Sentinel |
|---|---|---|
| 现状 | 停止维护(2018年) | 阿里开源,活跃维护 |
| 隔离方式 | 线程池隔离(资源消耗大) | 信号量 + 并发线程数限流 |
| 限流 | 不支持 | 支持(QPS + 并发数) |
| 控制台 | 简单 | 完善,可动态调整规则 |
新项目使用 Sentinel。
@SentinelResource(value = "getUserById",
fallback = "getUserFallback",
blockHandler = "getUserBlocked")
public User getUserById(Long id) {
return userService.findById(id);
}
public User getUserFallback(Long id, Throwable t) {
return new User(id, "未知用户", "降级返回");
}限流算法
| 算法 | 原理 | 特点 | 适用场景 |
|---|---|---|---|
| 漏桶 | 请求进队列,以固定速率流出 | 流量绝对平滑,不支持突发 | 消息队列消费控制 |
| 令牌桶 | 固定速率生成令牌,有令牌才能通过 | 允许突发,桶内令牌积累 | 秒杀、API 限流 |
| 滑动窗口 | 将单位时间分多格,动态统计 | 精确,解决固定窗口临界问题 | Nginx 限流 |
漏桶强制平滑,超出排队或丢弃;令牌桶允许短时突发,更灵活。
// Guava RateLimiter(令牌桶)
RateLimiter limiter = RateLimiter.create(100.0); // 100 QPS
if (limiter.tryAcquire()) {
process(request);
} else {
return Response.tooManyRequests();
}降级
降级是主动或被动地返回兜底结果,保证核心链路可用。
| 类型 | 触发时机 | 示例 |
|---|---|---|
| 主动降级 | 手动开关 | 大促前关闭推荐功能 |
| 被动降级 | 熔断器触发 | 支付超时,返回「稍后重试」 |
| 兜底降级 | 缓存、默认值 | 查询失败,返回缓存数据 |
核心链路(下单、支付)不能降级。降级要有兜底提示,不能直接返回错误。
隔离
隔离是防止故障扩散的的重要手段,通过资源隔离限制故障影响范围。
舱壁模式为不同服务分配独立资源池,避免一个服务耗尽所有资源。
Hystrix 使用线程池隔离(1000 线程 ≈ 2GB 内存),资源开销大;Sentinel 使用信号量隔离(无需创建额外线程),开销极低。
超时控制
超时是最基础的容错手段,必须为每个远程调用设置超时时间。
feign:
client:
config:
default:
connectTimeout: 1000 # 连接超时 1s
readTimeout: 3000 # 读取超时 3s治理策略优先级
流量治理的各层策略应按优先级依次部署,形成层层设防的容错体系:
限流 → 超时 → 隔离 → 熔断 → 降级限流在最外层拦截超额流量,超时防止请求无限等待,隔离限制故障影响范围,熔断快速切断故障链路,降级在极端情况下返回兜底结果。
适用场景
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 秒杀/抢购 | 限流 + 降级 | 削峰填谷,保护后端 |
| 支付/订单 | 超时 + 熔断 | 防止级联故障 |
| 第三方 API 调用 | 熔断 + 降级 | 外部服务不可控 |
| 大促活动 | 全链路限流 + 主动降级 | 提前关闭非核心功能 |
FAQ
Q: Sentinel 和 Hystrix 该选哪个? A: 新项目统一使用 Sentinel。Hystrix 已于 2018 年停止维护,Sentinel 由阿里开源且活跃维护,支持限流(QPS + 并发数)、熔断、热点参数限流、系统自适应保护等能力,控制台可动态调整规则。已有 Hystrix 项目可逐步迁移到 Sentinel。
Q: 漏桶和令牌桶有什么区别? A: 漏桶以固定速率处理请求,超出部分排队或丢弃,流量绝对平滑;令牌桶以固定速率生成令牌,桶内可积累令牌,允许短时突发流量。大多数场景用令牌桶更合适(如 Guava RateLimiter),需要严格平滑输出时用漏桶(如消息队列消费控制)。
Q: 降级和熔断有什么区别? A: 熔断是自动触发的保护机制,当失败率超过阈值时快速切断请求;降级是主动或被动地返回兜底结果。熔断是降级的一种触发手段——熔断器打开后,请求被降级处理。降级的范围更广,还包括手动开关关闭非核心功能、返回缓存数据等。