服务雪崩
服务雪崩是指由于某个微服务节点故障或高延迟,导致调用链路上的多个服务级联崩溃,最终整个系统不可用的现象。以下是详细解析和示意图:
1. 服务雪崩的触发原因
(1)依赖链故障(示意图)
- 关键点:如果最底层的服务E(如数据库)响应变慢或宕机,会导致上游服务(C→B→A)线程池被占满,依次崩溃。
(2)线程池阻塞(资源耗尽)
- 现象:服务C不可用 → 服务B的线程全部阻塞等待 → 服务A的线程池被占满 → 整个链路瘫痪。
2. 服务雪崩的典型场景
(1)流量激增(突发流量)
- 结果:服务C因无法处理高并发而崩溃,引发上游服务超时。
(2)重试风暴
- 问题:客户端自动重试(如HTTP重试)会导致流量放大,进一步压垮服务。
服务保护
一、服务保护核心方案图示
二、核心保护方案实现
1. 熔断器(Circuit Breaker)
原理图:
代码实现(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)
原理图:
代码实现(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)
分级策略图:
代码实现(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)
隔离效果图:
代码实现(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. 缓存保护
流程示意图:
代码实现(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 核心架构图
二、核心功能详解
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. 配置线程池规则
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)
熔断状态机:
代码实现:
// 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 降级
降级流程:
代码实现:
// 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自动调整阈值 | ✖️ 不支持 |
四、快速启动
- 下载 Sentinel Dashboard
- 添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 配置Dashboard地址:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080