微服务为什么必须做限流降级
微服务架构下,一个服务的不可用会通过调用链快速扩散,引发级联故障——上游服务的请求堆积耗尽线程池,导致上游也不可用,雪崩效应就此形成。限流和熔断是阻断雪崩的两道防线:限流控制入口流量,熔断保护调用链路。
Sentinel是阿里开源的流量治理组件,Spring Boot 3.x生态下与Spring Cloud Alibaba深度集成,提供流量控制、熔断降级、系统保护、热点参数限流等能力。相比Resilience4j,Sentinel的控制台可视化和动态规则配置更完善,适合国内技术栈。
Sentinel集成Spring Boot 3.x核心配置
Maven依赖配置:
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2023.0.1.2</version>
</dependency>
<!-- 如需使用@SentinelResource注解 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.7</version>
</dependency>
application.yaml核心配置:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
port: 8719 # 与控制台通信端口
eager: true # 应用启动时立即初始化Sentinel
datasource: # 规则持久化(推荐Nacos)
flow:
nacos:
server-addr: 127.0.0.1:8848
namespace: sentinel
group-id: DEFAULT_GROUP
data-id: ${spring.application.name}-flow-rules
rule-type: flow
degrade:
nacos:
server-addr: 127.0.0.1:8848
namespace: sentinel
group-id: DEFAULT_GROUP
data-id: ${spring.application.name}-degrade-rules
rule-type: degrade
规则持久化到Nacos是生产级部署的必选项。Sentinel默认将规则存储在内存中,应用重启后规则丢失。推模式(Nacos/ZooKeeper)保证规则在集群中一致且持久化。
流量控制规则配置与QPS限流
Sentinel支持三种流控模式:直接、关联、链路。生产中最常用的是直接模式(QPS限流):
// 编码方式配置流控规则(开发/测试环境可用)
@PostConstruct
public void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
// API接口QPS限流
FlowRule orderApiRule = new FlowRule();
orderApiRule.setResource("POST:/api/orders");
orderApiRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
orderApiRule.setCount(100); // 单机QPS上限100
orderApiRule.setLimitApp("default"); // 所有来源生效
orderApiRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
orderApiRule.setWarmUpPeriodSec(10); // 预热时长10秒
rules.add(orderApiRule);
FlowRuleManager.loadRules(rules);
}
控制行为CONTROL_BEHAVIOR_WARM_UP适用于冷启动场景——服务刚启动时处理能力未达峰值,预热模式让QPS阈值从1/3逐步提升到设定值,避免启动瞬间被大流量击穿。
更精细的限流用热点参数规则:
// 对同一个userId的请求频率限制
ParamFlowRule rule = new ParamFlowRule();
rule.setResource("/api/orders");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(5); // 每个参数值QPS上限5
rule.setParamIdx(0); // 限流参数索引(方法第0个参数)
rule.setDurationInSec(1); // 统计窗口1秒
// 特定参数值单独配置
ParamFlowItem item = new ParamFlowItem();
item.setObject("vip-user-123"); // VIP用户
item.setClassType(String.class.getName());
item.setCount(20); // VIP用户QPS上限20
rule.setParamFlowItemList(List.of(item));
ParamFlowRuleManager.loadRules(List.of(rule));
熔断降级规则与慢调用比例策略
熔断器的三种策略:慢调用比例、异常比例、异常数。慢调用比例是最贴近生产实际的策略:
// 慢调用比例熔断规则
DegradeRule slowCallRule = new DegradeRule();
slowCallRule.setResource("/api/payment/process");
slowCallRule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());
slowCallRule.setCount(500); // 慢调用阈值:响应时间超过500ms
slowCallRule.setSlowRatioThreshold(0.6); // 慢调用比例阈值:60%
slowCallRule.setTimeWindow(10); // 熔断持续时长10秒
slowCallRule.setMinRequestAmount(5); // 最小请求数:5
slowCallRule.setStatIntervalMs(5000); // 统计时长5秒
DegradeRuleManager.loadRules(List.of(slowCallRule));
熔断状态机流转:
1. CLOSED(正常):请求正常通过,统计慢调用比例。
2. OPEN(熔断):慢调用比例超过阈值,所有请求直接拒绝,触发降级逻辑。
3. HALF-OPEN(半开):熔断10秒后,放行1个探测请求。如果探测请求正常(响应时间低于500ms),恢复到CLOSED;如果仍然慢调用,重新进入OPEN。
minRequestAmount设为5是为了避免低流量下偶发慢调用触发熔断——5秒内不足5个请求时,统计样本不够,不触发熔断判断。
@SentinelResource注解与自定义降级处理
@SentinelResource注解可以精确到方法级别的流量控制:
@Service
public class OrderService {
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlockHandler", // 限流处理
blockHandlerClass = OrderBlockHandler.class,
fallback = "createOrderFallback", // 降级处理
fallbackClass = OrderFallbackHandler.class
)
public OrderResult createOrder(OrderRequest request) {
// 正常业务逻辑
return orderProcessor.process(request);
}
}
// 限流处理器(触发流控规则时调用)
public class OrderBlockHandler {
public static OrderResult createOrderBlockHandler(
OrderRequest request, BlockException ex) {
return OrderResult.fail("系统繁忙,请稍后重试");
}
}
// 降级处理器(触发熔断规则或业务异常时调用)
public class OrderFallbackHandler {
public static OrderResult createOrderFallback(
OrderRequest request, Throwable throwable) {
// 降级逻辑:写入MQ异步处理,返回排队提示
mqProducer.send(createOrderMessage(request));
return OrderResult.accept("订单已排队处理");
}
}
blockHandler和fallback的区别:blockHandler处理限流/熔断触发(BlockException),fallback处理业务异常(Throwable)。两者可以同时配置,不同异常走不同降级路径。
集群限流与网关层全局流控
单机限流在分布式环境下存在精度问题——100个实例每个限100QPS,集群总QPS上限实际是10000,但无法保证均匀分布。集群限流通过Token Server统一分配令牌:
# application.yaml - 集群限流客户端配置
spring:
cloud:
sentinel:
transport:
dashboard: sentinel-dashboard:8080
cluster:
mode: client # 集群限流客户端
client-config:
requestTimeout: 200 # 令牌请求超时
---
# Token Server独立部署配置
spring:
cloud:
sentinel:
cluster:
mode: server
server-config:
port: 18730 # Token Server端口
max-idle-time: 600000 # 空闲连接超时
idle-check-interval: 60000
网关层(Spring Cloud Gateway + Sentinel)的全局流控是最后一道防线:
// Gateway限流配置
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 500
redis-rate-limiter.burstCapacity: 1000
key-resolver: "#{@userKeyResolver}"
// KeyResolver配置
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getHeaders().getFirst("X-User-Id") != null
? exchange.getRequest().getHeaders().getFirst("X-User-Id")
: "anonymous"
);
}
三层防线串联:网关层全局限流 → 服务层QPS限流 → 方法级熔断降级,任何一层过载都会触发保护机制,防止故障扩散。生产环境务必全链路配置,不能只依赖某一层。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot3x-wei-fu-wu-xian-liu-jiang-ji-yu-sentinel-rong/