12. 限流、熔断与降级

分布式系统韧性设计:令牌桶/漏桶/滑动窗口限流、熔断器模式、降级策略与 Sentinel 实战

高并发场景下,系统需具备自我保护能力。限流控制入口流量,熔断防止故障扩散,降级保障核心业务。三者构成分布式系统的韧性防线。

1. 限流算法

1.1 计数器(固定窗口)

public class FixedWindowRateLimiter {
    private final long windowSizeMs;
    private final int maxRequests;
    private final AtomicInteger counter = new AtomicInteger(0);
    private volatile long windowStart = System.currentTimeMillis();
    
    public synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();
        if (now - windowStart >= windowSizeMs) {
            counter.set(0);
            windowStart = now;
        }
        return counter.incrementAndGet() <= maxRequests;
    }
}

缺点:窗口边界可能突发 2 倍流量。

1.2 滑动窗口

public class SlidingWindowRateLimiter {
    private final int maxRequests;
    private final long windowMs;
    private final Queue<Long> timestamps = new LinkedList<>();
    
    public synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();
        long boundary = now - windowMs;
        
        while (!timestamps.isEmpty() && timestamps.peek() <= boundary) {
            timestamps.poll();
        }
        
        if (timestamps.size() < maxRequests) {
            timestamps.offer(now);
            return true;
        }
        return false;
    }
}

1.3 令牌桶

public class TokenBucket {
    private final long capacity;
    private final long refillRate;  // tokens per second
    private double tokens;
    private long lastRefillTimestamp;
    
    public synchronized boolean tryAcquire(int requestedTokens) {
        refill();
        if (tokens >= requestedTokens) {
            tokens -= requestedTokens;
            return true;
        }
        return false;
    }
    
    private void refill() {
        long now = System.currentTimeMillis();
        double tokensToAdd = (now - lastRefillTimestamp) * refillRate / 1000.0;
        tokens = Math.min(capacity, tokens + tokensToAdd);
        lastRefillTimestamp = now;
    }
}

1.4 漏桶

漏桶以固定速率处理请求,超出容量的请求被丢弃。实现上可以用队列 + 定时消费。

2. 熔断器 (Circuit Breaker)

2.1 状态机

CLOSED ──(失败率>阈值)──→ OPEN
   ↑                         │
   └──(超时后半开)──────── HALF-OPEN ──(成功)──┘
                              └──(失败)──→ OPEN
状态行为
CLOSED正常放行,统计错误率
OPEN直接拒绝,返回降级
HALF-OPEN放行少量请求试探

2.2 Resilience4j 实现

// 配置熔断器
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
    .failureRateThreshold(50)          // 失败率阈值 50%
    .slowCallRateThreshold(80)         // 慢调用阈值
    .slowCallDurationThreshold(Duration.ofSeconds(2))
    .permittedNumberOfCallsInHalfOpenState(10)
    .slidingWindowSize(100)
    .waitDurationInOpenState(Duration.ofSeconds(30))
    .build();

CircuitBreaker circuitBreaker = CircuitBreaker.of("orderService", config);

// 使用
Supplier<String> decorated = CircuitBreaker.decorateSupplier(
    circuitBreaker, 
    () -> orderService.createOrder(request)
);

try {
    String result = decorated.get();
} catch (CallNotPermittedException e) {
    // 熔断器 OPEN,执行降级
    return fallbackService.createOrder(request);
}

3. 降级策略

策略场景
默认值返回缓存的静态数据
功能降级关闭非核心功能(推荐算法 → 默认排序)
页面降级返回简化版页面
数据降级返回部分字段而非全量
读降级写请求正常,读请求降级

4. Sentinel 实战

// 限流规则
FlowRule rule = new FlowRule();
rule.setResource("queryOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(1000);
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
rule.setWarmUpPeriodSec(10);
FlowRuleManager.loadRules(Collections.singletonList(rule));

// 使用
Entry entry = null;
try {
    entry = SphU.entry("queryOrder");
    return orderService.query(orderId);
} catch (BlockException e) {
    return fallbackQuery(orderId);
} finally {
    if (entry != null) entry.exit();
}

5. 三层防护体系

┌─────────────────────────────────────────┐
│  接入层:Nginx/Spring Cloud Gateway      │
│  限流:IP/QPS/并发数                      │
├─────────────────────────────────────────┤
│  服务层:Sentinel/Resilience4j          │
│  熔断 + 限流 + 降级                      │
├─────────────────────────────────────────┤
│  资源层:HikariCP/Redis/Guava           │
│  连接池限流、线程池隔离                   │
└─────────────────────────────────────────┘

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「distributed-systems」更多文章

  1. 分布式高可用架构模式:多活、容灾、降级与 K8s 编排高可用
  2. 分布式链路追踪实战:OpenTelemetry、Jaeger 与 W3C Trace Context
  3. 分布式缓存深度策略:Redis Cluster、一致性哈希与多级缓存架构