202525 | 服务雪崩 | 服务保护 | Sentinel

发布于:2025-04-15 ⋅ 阅读:(23) ⋅ 点赞:(0)

服务雪崩

服务雪崩是指由于某个微服务节点故障或高延迟,导致调用链路上的多个服务级联崩溃,最终整个系统不可用的现象。以下是详细解析和示意图:


1. 服务雪崩的触发原因

(1)依赖链故障(示意图)
用户请求
服务A
服务B
服务C
数据库/外部API
  • 关键点:如果最底层的服务E(如数据库)响应变慢或宕机,会导致上游服务(C→B→A)线程池被占满,依次崩溃。
(2)线程池阻塞(资源耗尽)
调用超时
全部阻塞
服务A: 100线程
服务B: 50线程
服务C: 已宕机
  • 现象:服务C不可用 → 服务B的线程全部阻塞等待 → 服务A的线程池被占满 → 整个链路瘫痪。

2. 服务雪崩的典型场景

(1)流量激增(突发流量)
突发流量
服务A
服务B
服务C: 性能瓶颈
  • 结果:服务C因无法处理高并发而崩溃,引发上游服务超时。
(2)重试风暴
超时重试x3
其他请求
雪崩加剧
服务A
服务B: 已过载
服务C
  • 问题:客户端自动重试(如HTTP重试)会导致流量放大,进一步压垮服务。

服务保护

一、服务保护核心方案图示
服务保护
熔断器
限流
降级
隔离
缓存
异步化
快速失败
控制QPS
返回兜底数据
线程池隔离
本地缓存
消息队列

二、核心保护方案实现
1. 熔断器(Circuit Breaker)

原理图

服务A 服务B 正常请求 成功响应 连续失败5次 新请求 直接拒绝(熔断状态) 10秒后尝试恢复 服务A 服务B

代码实现(Resilience4j)

// 1. 配置熔断规则
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
    .failureRateThreshold(50) // 失败率阈值50%
    .slidingWindowSize(10)    // 统计窗口大小
    .waitDurationInOpenState(Duration.ofSeconds(10))
    .build();

// 2. 创建熔断器实例
CircuitBreaker circuitBreaker = CircuitBreaker.of("userService", config);

// 3. 保护方法调用
Supplier<String> decoratedSupplier = CircuitBreaker
    .decorateSupplier(circuitBreaker, () -> userService.getUser(id));

// 4. 执行(带降级)
Try.ofSupplier(decoratedSupplier)
    .recover(throwable -> "fallback-user") // 降级逻辑
    .get();

2. 限流(Rate Limiting)

原理图

1000 QPS
放行500 QPS
拒绝500 QPS
大量请求
限流器
服务
返回429

代码实现(Sentinel)

// 1. 定义资源
@SentinelResource(value = "getOrder", blockHandler = "blockHandler")
public Order getOrder(String orderId) {
    return orderService.query(orderId);
}

// 2. 限流处理逻辑
public Order blockHandler(String orderId, BlockException ex) {
    throw new RuntimeException("系统繁忙,请稍后重试");
}

// 3. 动态规则配置(可通过Sentinel Dashboard)
FlowRule rule = new FlowRule();
rule.setResource("getOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(500); // 阈值500 QPS
FlowRuleManager.loadRules(Collections.singletonList(rule));

3. 降级(Fallback)

分级策略图

45% 35% 20% 降级策略分布 静态降级 缓存降级 备用服务

代码实现(Spring Cloud OpenFeign)

// 1. Feign客户端声明
@FeignClient(
    name = "payment-service",
    fallback = PaymentFallback.class
)
public interface PaymentClient {
    @PostMapping("/pay")
    String pay(@RequestBody Order order);
}

// 2. 降级实现类
@Component
public class PaymentFallback implements PaymentClient {
    @Override
    public String pay(Order order) {
        return "支付服务暂不可用"; // 静态降级
    }
}

4. 线程隔离(Bulkhead)

隔离效果图

服务B
服务A
独立资源
独立资源
线程池B-5线程
线程池A-10线程
数据库

代码实现(Hystrix)

@HystrixCommand(
    commandKey = "inventoryService",
    threadPoolKey = "inventoryPool",
    threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "10"),
        @HystrixProperty(name = "maxQueueSize", value = "100")
    },
    fallbackMethod = "fallback"
)
public StockInfo getStock(String sku) {
    return stockService.query(sku);
}

public StockInfo fallback(String sku) {
    return new StockInfo(sku, 0); // 降级数据
}

5. 缓存保护

流程示意图

Client Server LocalCache DB 请求数据 检查缓存 返回数据 查询数据库 返回数据 写入缓存 alt [缓存命中] [缓存未命中] 返回结果 Client Server LocalCache DB

代码实现(Caffeine)

// 1. 初始化缓存
LoadingCache<String, User> cache = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(5, TimeUnit.MINUTES)
    .build(key -> userDao.get(key)); // 缓存未命中时加载

// 2. 使用缓存
public User getUser(String id) {
    try {
        return cache.get(id);
    } catch (Exception e) {
        log.error("缓存异常", e);
        return userDao.get(id); // 降级到数据库
    }
}

三、技术选型对比表
方案 适用场景 推荐工具 性能影响
熔断器 外部服务调用 Resilience4j/Sentinel
限流 入口流量控制 Sentinel/Redis
降级 非核心链路 Hystrix/Feign
线程隔离 资源敏感型服务 Hystrix
缓存 读多写少场景 Caffeine/Redis 极低

Apache Sentinel 深度解析

Sentinel 是阿里巴巴开源的流量控制与系统保护组件,提供限流、隔离、熔断、降级等能力。以下是核心功能的详细说明与可视化实现。


一、Sentinel 核心架构图
客户端/服务端
Sentinel Core
规则管理
流量统计
流量控制
系统保护
动态规则配置
QPS/线程数/响应时间
限流/熔断/隔离
Load/CPU/RT保护

二、核心功能详解

1. 请求限流(Flow Control)

原理图

通过
拒绝
请求进入
限流检查
处理请求
返回限流提示
返回响应

代码实现

// 1. 定义资源(注解方式)
@SentinelResource(value = "queryOrder", blockHandler = "handleBlock")
public Order queryOrder(String orderId) {
    return orderService.getById(orderId);
}

// 2. 限流处理逻辑
public Order handleBlock(String orderId, BlockException ex) {
    throw new OrderException(429, "请求过于频繁");
}

// 3. 动态规则配置(通过Dashboard或代码)
FlowRule rule = new FlowRule();
rule.setResource("queryOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS限流模式
rule.setCount(100); // 阈值100 QPS
FlowRuleManager.loadRules(Collections.singletonList(rule));

限流算法对比

算法 原理 适用场景
直接拒绝 超阈值立即返回错误 突发流量控制
预热模式 缓慢提升阈值至设定值 冷启动保护
排队等待 请求进入队列匀速处理 流量平滑

2. 线程隔离(Thread Isolation)

隔离模型图

线程池1
线程池2
请求
线程池选择
服务A
服务B

代码实现

// 1. 配置线程池规则
DegradeRule threadRule = new DegradeRule();
threadRule.setResource("paymentService");
threadRule.setGrade(RuleConstant.DEGRADE_GRADE_THREAD_COUNT);
threadRule.setCount(50); // 最大线程数50
threadRule.setTimeWindow(10); // 统计窗口10秒
DegradeRuleManager.loadRules(Collections.singletonList(threadRule));

// 2. 资源定义
@SentinelResource(
    value = "paymentService",
    blockHandler = "paymentBlockHandler",
    fallback = "paymentFallback"
)
public String pay(Order order) {
    return paymentClient.execute(order);
}

隔离策略对比

类型 实现方式 开销
线程池隔离 独立线程池处理请求
信号量隔离 计数器控制并发数

3. 服务熔断(Circuit Breaking)

熔断状态机

失败超阈值
探测恢复期
探测成功
探测失败
Closed
Open
HalfOpen

代码实现

// 1. 熔断规则配置
DegradeRule rule = new DegradeRule();
rule.setResource("inventoryService");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setCount(5); // 5次异常触发熔断
rule.setTimeWindow(30); // 熔断持续时间30秒
DegradeRuleManager.loadRules(Collections.singletonList(rule));

// 2. 资源注解
@SentinelResource(
    value = "inventoryService",
    fallback = "inventoryFallback",
    blockHandler = "inventoryBlockHandler"
)
public Stock reduceStock(String sku) {
    return inventoryClient.deduct(sku);
}

熔断触发条件

  • 异常比例 ≥ 阈值(默认50%)
  • 异常数量 ≥ 阈值(默认5次)
  • 平均RT超时

4. Fallback 降级

降级流程

Consumer Sentinel Provider 请求服务 转发请求 返回结果 返回结果 执行Fallback逻辑 alt [正常情况] [触发规则] Consumer Sentinel Provider

代码实现

// 1. 定义Fallback方法(需与原方法同参数)
public String paymentFallback(Order order, Throwable ex) {
    return "支付服务降级处理中";
}

// 2. 资源注解配置
@SentinelResource(
    value = "paymentService",
    fallback = "paymentFallback",
    exceptionsToTrace = {Exception.class}
)
public String pay(Order order) {
    // 业务逻辑
}

降级策略

  • 静态降级:返回固定值
  • 动态降级:读取缓存/备用服务
  • 人工降级:通过Sentinel Dashboard手动触发

三、Sentinel vs Hystrix 对比

功能 Sentinel Hystrix
限流 ✔️ 支持QPS/线程数/系统负载多维度 ✖️ 仅支持线程池/信号量
熔断 ✔️ 基于异常数/比例/RT多策略 ✔️ 仅支持异常比例
实时监控 ✔️ 内置Dashboard ✖️ 依赖Turbine
动态规则 ✔️ 支持Nacos/ZooKeeper动态推送 ✖️ 仅静态配置
系统自适应保护 ✔️ 根据Load/CPU/RT自动调整阈值 ✖️ 不支持

四、快速启动

  1. 下载 Sentinel Dashboard
  2. 添加依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. 配置Dashboard地址:
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080

网站公告

今日签到

点亮在社区的每一天
去签到