微服务限流降级的核心场景
微服务架构中,限流降级是保障系统稳定性的最后一道防线。当上游流量突增、下游依赖超时、缓存穿透等异常发生时,没有限流保护的节点会像多米诺骨牌一样逐级崩溃。Spring Boot 3.x整合Alibaba Sentinel,能实现细粒度的流量控制、熔断降级和热点参数限流,覆盖网关层和服务层的双重防护。这篇实战指南从配置到源码级分析,解决实际生产环境中的限流降级需求。
Spring Boot 3.x整合Sentinel基础配置
依赖引入
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.8</version>
</dependency>
application.yml配置
spring:
application:
name: order-service
cloud:
sentinel:
transport:
dashboard: sentinel-dashboard:8080
port: 8719
datasource:
flow:
nacos:
server-addr: nacos:8848
namespace: sentinel
group-id: SENTINEL_GROUP
data-id: ${spring.application.name}-flow-rules
rule-type: flow
degrade:
nacos:
server-addr: nacos:8848
namespace: sentinel
group-id: SENTINEL_GROUP
data-id: ${spring.application.name}-degrade-rules
rule-type: degrade
规则存储在Nacos中,多实例共享规则且支持动态修改。不依赖Dashboard推送,避免Dashboard宕机导致规则丢失。
流量控制:QPS限流与线程隔离
注解方式限流
@Service
public class OrderService {
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlock",
fallback = "createOrderFallback"
)
public OrderResult createOrder(OrderRequest request) {
// 业务逻辑
return orderClient.submit(request);
}
// 限流处理:QPS超限触发
public OrderResult createOrderBlock(OrderRequest request, BlockException ex) {
log.warn("订单接口限流触发: {}", ex.getRule());
return OrderResult.fail("SYSTEM_BUSY", "系统繁忙,请稍后重试");
}
// 降级处理:业务异常触发
public OrderResult createOrderFallback(OrderRequest request, Throwable t) {
log.error("订单创建降级: {}", t.getMessage());
return OrderResult.fail("SERVICE_DEGRADE", "服务降级中");
}
}
编程式限流:更灵活的控制
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@PostMapping
public ResponseEntity<?> createOrder(@RequestBody OrderRequest req) {
Entry entry = null;
try {
entry = SphU.entry("createOrder", EntryType.IN);
// 业务逻辑
OrderResult result = orderService.createOrder(req);
return ResponseEntity.ok(result);
} catch (BlockException e) {
return ResponseEntity.status(429)
.body(Map.of("code", "RATE_LIMITED", "msg", "请求过于频繁"));
} catch (Exception e) {
Tracer.traceEntry(e, entry);
return ResponseEntity.status(500)
.body(Map.of("code", "INTERNAL_ERROR", "msg", "服务异常"));
} finally {
if (entry != null) entry.exit();
}
}
}
热点参数限流:按用户ID限流
// 规则:同一用户10秒内最多5次请求
ParamFlowRule rule = new ParamFlowRule("createOrder")
.setParamIdx(0) // 第一个参数作为限流维度
.setCount(5)
.setGrade(RuleConstant.FLOW_GRADE_QPS);
ParamFlowItem item = new ParamFlowItem()
.setObject("vip_user")
.setClassType(String.class.getName())
.setCount(20); // VIP用户放宽到20
rule.setParamFlowItemList(List.of(item));
ParamFlowRuleManager.loadRules(List.of(rule));
熔断降级:三种熔断策略配置
策略1:慢调用比例熔断
// 当慢调用比例超过50%且请求量>=5时触发熔断
DegradeRule slowRule = new DegradeRule("paymentService")
.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
.setCount(500) // 慢调用阈值:500ms
.setSlowRatioThreshold(0.5) // 慢调用比例阈值:50%
.setTimeWindow(30) // 熔断时长:30秒
.setMinRequestAmount(5) // 最小请求数
.setStatIntervalMs(10000); // 统计时间窗口:10秒
策略2:异常比例熔断
DegradeRule errorRatioRule = new DegradeRule("inventoryService")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.3) // 异常比例阈值:30%
.setTimeWindow(20) // 熔断时长:20秒
.setMinRequestAmount(10)
.setStatIntervalMs(10000);
策略3:异常数熔断
DegradeRule errorCountRule = new DegradeRule("userService")
.setGrade(CircuitBreakerStrategy.ERROR_COUNT.getType())
.setCount(10) // 异常数阈值:10次
.setTimeWindow(60) // 熔断时长:60秒
.setMinRequestAmount(20)
.setStatIntervalMs(60000);
加载规则:
DegradeRuleManager.loadRules(List.of(slowRule, errorRatioRule, errorCountRule));
Gateway网关层限流配置
网关层做全局限流,服务层做精细限流,双层防护:
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.8</version>
</dependency>
@Configuration
public class GatewayConfig {
@PostConstruct
public void init() {
// 按路由ID限流
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("order-service-route")
.setCount(500) // QPS 500
.setIntervalSec(1));
rules.add(new GatewayFlowRule("user-service-route")
.setCount(1000)
.setIntervalSec(1));
// 按IP维度限流
rules.add(new GatewayFlowRule("order-service-route")
.setCount(50)
.setIntervalSec(1)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_IP)
));
GatewayRuleManager.loadRules(rules);
}
@Bean
@Order(-1)
public SentinelGatewayFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayBlockFilter() {
return (exchange, chain) -> {
ServerHttpResponse resp = exchange.getResponse();
resp.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
resp.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = "{\"code\":429,\"msg\":\"Gateway rate limited\"}";
DataBuffer buffer = resp.bufferFactory().wrap(body.getBytes());
return resp.writeWith(Mono.just(buffer));
};
}
}
限流降级效果验证与压测
# 使用wrk压测限流效果
# 先启动服务,配置QPS=100的限流规则
wrk -t4 -c100 -d30s --latency http://localhost:8080/api/orders
# 对比限流前后:
# 限流前:QPS 200+,错误率上升(服务过载)
# 限流后:QPS稳定在100,超限请求返回429
# 观察Sentinel Dashboard的实时监控
# 查看通过QPS、拒绝QPS、平均响应时间、异常比例
压测要点:逐步增加并发量,观察在QPS达到限流阈值时的行为——通过请求正常返回,超限请求返回429,响应时间不退化。
生产环境限流降级检查清单
- 所有对外接口是否配置了QPS限流规则
- 核心依赖是否配置了熔断降级(至少慢调用比例+异常比例)
- 限流规则的blockHandler是否返回友好的错误码和提示
- 热点参数限流是否覆盖了按用户维度的限制
- Gateway全局限流规则是否与下游服务限流配合
- 规则是否持久化到Nacos/Apollo,避免重启丢失
- 熔断恢复后是否有预热机制(避免瞬间流量冲击恢复中的服务)
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot3x-wei-fu-wu-xian-liu-jiang-ji-yu-sentinel-ji/