为什么需要熔断限流?从一次生产事故说起

核心观点: 熔断限流不是性能优化,而是系统稳定性的生命线。本文从一次真实生产事故出发,深度剖析为什么微服务架构必须要有熔断限流机制。 引子:2024年11月11日,一次惊心动魄的生产事故 事故背景 某电商平台,日常订单量10万单/天,流量1000 QPS。2024年双十一活动,预计流量增长3-5倍。技术团队提前扩容服务器,增加数据库连接池,准备迎接流量高峰。 然而,谁也没想到,活动开始仅10分钟,整个系统就崩溃了。 时间线复盘 10:00:00 - 活动正式开始 运营团队启动促销活动,用户涌入。前端监控显示流量快速攀升: 10:00:00 → 1,000 QPS(正常) 10:02:00 → 3,000 QPS(预期内) 10:05:00 → 8,000 QPS(超预期) 10:08:00 → 12,000 QPS(远超预期) 10:05:30 - 第一个异常信号 监控系统开始报警: [ALERT] 订单服务响应时间: 50ms → 800ms (P99) [ALERT] 订单服务线程池占用: 50/200 → 180/200 技术团队看到告警,以为是正常的流量压力,决定继续观察。 10:07:15 - 雪崩的开始 [CRITICAL] 订单服务响应时间: 800ms → 5000ms (P99) [CRITICAL] 订单服务线程池占用: 200/200 (100%,线程池耗尽) [ERROR] 用户服务调用超时: connection timeout after 5s 技术团队意识到不对劲,开始排查。日志显示: java.net.SocketTimeoutException: Read timed out at UserServiceClient.getUser(UserServiceClient.java:45) at OrderService.createOrder(OrderService.java:87) ... 原因找到了:用户服务的数据库出现慢查询(某个未加索引的查询,平时10ms,高峰期变成5秒)。 ...

2025-11-03 · maneng

熔断降级实战:从Hystrix到Sentinel

核心观点: 熔断器是微服务架构的安全气囊,通过快速失败隔离故障,防止雪崩。Sentinel是当前生产环境的最佳选择。 熔断器核心原理 什么是熔断器? 熔断器(Circuit Breaker)借鉴了电路中的断路器概念: 电路断路器: 正常 → 短路 → 断路器跳闸 → 保护电路 服务熔断器: 正常 → 下游故障 → 熔断器打开 → 保护上游 核心思想: 当下游服务故障时,快速失败优于漫长等待。 熔断器状态机 熔断器有三种状态: 错误率>阈值 Closed ───────────→ Open ↑ │ │ │ 等待恢复时间 │ ↓ │ Half-Open │ │ │ 探测成功 │ 探测失败 └──────────────────┘ 状态说明: Closed(闭合): 正常状态 放行所有请求 统计错误率 错误率>阈值 → 转Open Open(打开): 熔断状态 拒绝所有请求,快速失败 不调用下游服务 等待一段时间 → 转Half-Open Half-Open(半开): 探测状态 放行少量请求(探测) 成功 → 转Closed 失败 → 转Open 手写熔断器 /** * 简化版熔断器 */ public class SimpleCircuitBreaker { // 状态枚举 enum State { CLOSED, OPEN, HALF_OPEN } private State state = State.CLOSED; private int failureCount = 0; private int successCount = 0; private long lastFailureTime = 0; // 配置 private final int failureThreshold; // 失败阈值 private final long timeoutMillis; // 熔断时长 private final int halfOpenSuccessThreshold; // 半开成功阈值 public SimpleCircuitBreaker(int failureThreshold, long timeoutMillis) { this.failureThreshold = failureThreshold; this.timeoutMillis = timeoutMillis; this.halfOpenSuccessThreshold = 3; } /** * 执行受保护的调用 */ public <T> T execute(Callable<T> callable, Function<Exception, T> fallback) { // 检查状态 if (state == State.OPEN) { // 检查是否可以进入半开状态 if (System.currentTimeMillis() - lastFailureTime >= timeoutMillis) { state = State.HALF_OPEN; successCount = 0; } else { // 快速失败,调用降级 return fallback.apply(new CircuitBreakerOpenException()); } } try { // 调用实际方法 T result = callable.call(); // 调用成功 onSuccess(); return result; } catch (Exception e) { // 调用失败 onFailure(); return fallback.apply(e); } } private synchronized void onSuccess() { failureCount = 0; if (state == State.HALF_OPEN) { successCount++; if (successCount >= halfOpenSuccessThreshold) { // 连续成功,恢复闭合 state = State.CLOSED; } } } private synchronized void onFailure() { lastFailureTime = System.currentTimeMillis(); if (state == State.HALF_OPEN) { // 半开状态失败,立即打开 state = State.OPEN; successCount = 0; } else if (state == State.CLOSED) { failureCount++; if (failureCount >= failureThreshold) { // 失败次数达到阈值,打开熔断器 state = State.OPEN; } } } public State getState() { return state; } } // 使用示例 public class UserService { private SimpleCircuitBreaker breaker = new SimpleCircuitBreaker(5, 10000); // 5次失败,熔断10秒 public User getUser(Long userId) { return breaker.execute( // 实际调用 () -> userServiceClient.getUser(userId), // 降级方法 (ex) -> { log.warn("用户服务熔断,返回默认用户"); return User.defaultUser(userId); } ); } } 工作流程: ...

2025-11-03 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...