架构之高并发:降级与熔断实战全攻略
在互联网高并发场景中,系统架构不仅要追求高吞吐量和低延迟,更要具备 抗风险能力。一次流量洪峰、一次依赖服务故障,就可能引发 雪崩效应。
降级(Downgrade)和 熔断(Circuit Breaker),正是防止雪崩、保障核心业务稳定的核心手段。
1. 为什么必须要做降级与熔断?
典型的高并发危机:
- 秒杀开始几秒内,大量用户请求导致数据库连接池耗尽。
- 首页依赖的推荐服务宕机,用户等待超时。
- 第三方服务延迟,使调用链被拖慢,影响上游业务。
微服务调用链示例: 用户请求 → API网关 → 用户服务 → 推荐服务 → 数据服务 → 第三方接口
当链路中的某个环节出问题,如果不隔离故障,就会导致全链路阻塞,最终系统不可用。
2. 概念解析
2.1 降级(Fallback / Downgrade)
定义:当某个服务不可用或负载过高时,不再调用它,而是临时关闭部分功能或返回替代数据,以保障核心业务正常运行。
特征:
- 主动牺牲非核心功能。
- 保留关键业务闭环。
- 常常返回静态内容或缓存数据。
常见类型:
- 静态降级:返回固定文案或图片。
- 缓存降级:从 Redis 或本地缓存返回旧数据。
- 功能降级:关闭非关键功能(如首页推荐模块)。
- 限流降级:限制部分用户访问,保障 VIP 或核心功能。
2.2 熔断(Circuit Breaker)
定义:类似电路的保护机制,当调用错误率或延迟率持续超过预设阈值时,自动“断开”对故障服务的调用,防止雪崩。
特征:
- 切断异常服务调用。
- 避免浪费资源等待无效响应。
- 支持半开状态试探恢复。
状态机:
- Closed(关闭):正常调用。
- Open(打开):触发熔断,直接失败或走降级逻辑。
- Half-Open(半开):试探性恢复,成功则回到 Closed,否则继续 Open。
3. 降级与熔断的差异与联系
| 比较项 | 降级 | 熔断 |
|---|---|---|
| 核心目标 | 保留关键功能,牺牲非核心功能 | 切断无效调用,防止雪崩 |
| 触发条件 | 流量高峰、资源不足、依赖不可用 | 错误率/延迟超阈值 |
| 粒度 | 功能级、接口级 | 微服务调用级 |
4. 实战落地案例:从代码到架构
场景设定
双十一当天零点,淘宝 APP 的访问量暴涨:
-
第一波流量洪峰集中在 首页(用户看活动、领优惠券)
-
同时大量用户进入商品详情页、点击立即下单
-
几乎所有链路都会调用多个下游服务,例如:
- 商品服务:实时拉取价格、库存
- 营销服务:实时计算优惠券、满减活动
- 推荐服务:智能推荐商品
- 评价服务:展示评价内容
- 物流配送服务:计算运费和可达时间
4.1 降级典型案例:评价服务降级
问题
商品详情页除了商品信息,还要加载海量评价,这个接口并不是下单的核心。
在双十一高峰期,评价服务压力可能很大,响应延迟会拖慢整个详情页加载。
降级策略
- 当评价服务响应超时或失败时,不再调用实时服务
- 直接返回最近一次缓存的评价数据,或者干脆不展示评价入口
- Java + Resilience4j 示例:
@SentinelResource(
value = "productReviewService",
fallback = "reviewFallback"
)
public List<Review> getProductReviews(Long productId) {
return reviewServiceClient.fetchReviews(productId);
}
// 降级处理
public List<Review> reviewFallback(Throwable ex) {
log.warn("Review service degraded: {}", ex.getMessage());
return redisTemplate.opsForList().range("review_cache_" + productId, 0, 20);
}
好处
- 保证商品详情页能在 300ms 内加载完毕
- 用户仍能看到商品关键信息和价格,不影响下单行为
4.2 熔断典型案例:优惠券服务熔断
问题
结算页面会调用“优惠券服务”来计算可用优惠券,如果优惠券服务延迟或失败,会导致结算请求一直卡住,用户无法下单。
熔断策略
- 如果过去 10 秒内优惠券接口的失败率超过 50%,触发熔断
- 在熔断期间,直接提示用户“暂时无法获取优惠券”,让用户可以先支付
- 熔断结束后进入半开状态,测试服务是否恢复
- Java + Sentinel 示例:
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率阈值
.waitDurationInOpenState(Duration.ofSeconds(10)) // 熔断时长
.slidingWindowSize(20) // 时间窗口
.build();
CircuitBreaker breaker = CircuitBreakerRegistry.of(config)
.circuitBreaker("couponService");
Supplier<DiscountInfo> supplier =
CircuitBreaker.decorateSupplier(breaker, () -> couponService.getAvailableCoupons(userId));
try {
DiscountInfo info = supplier.get();
} catch (CallNotPermittedException e) {
log.warn("Coupon service unavailable, fallback to default");
info = new DiscountInfo(Collections.emptyList()); // 无优惠券
}
好处
- 避免因为优惠券接口挂掉引起订单提交超时
- 用户下单流程不中断,活动核心链路(交易)得以保障
5. 总结 & 行动清单
降级与熔断是高并发系统的 防护网,它们不是性能优化手段,而是可用性保障措施。
行动清单:
- 梳理业务优先级,明确可降级功能。
- 给所有外部依赖加熔断器。
- 接入监控与告警系统。
- 每季度进行降级与熔断演练。