流量控制(Flow Control)
/api/order
限制 QPS=100);/web
路径的请求进行限制)。熔断与降级(Circuit Breaking & Fallback)
@SentinelResource
注解的 blockHandler
或 fallback
属性实现。系统自适应保护
动态规则推送
支持通过控制台实时修改规则并推送至客户端,无需重启服务。例如,运维人员可直接在 Dashboard 调整限流阈值,规则秒级生效。
精细化资源管理
@SentinelResource
标记需保护的资源(如方法、接口),与代码解耦;多场景兼容性
spring-cloud-starter-alibaba-sentinel
依赖快速接入;控制台部署
sentinel-dashboard-1.8.6.jar
),通过 java -jar
启动,默认端口 8080,登录账号为 sentinel/sentinel
。客户端集成
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
application.yml
中指定 Dashboard 地址和通信端口:spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719 # 客户端与控制台交互端口
规则配置示例
代码注解:
@GetMapping("/order/create")
@SentinelResource(value = "createOrder", blockHandler = "handleBlock", fallback = "handleFallback")
public String createOrder() {
// 业务逻辑
}
// 限流/降级处理逻辑
public String handleBlock(BlockException ex) {
return "系统繁忙,请稍后再试!";
}
控制台配置:通过 Dashboard 界面动态添加流控规则,支持设置 QPS、熔断时长等参数。
高并发场景
容灾与稳定性保障
企业级最佳实践
同步场景下,Sentinel 直接通过线程本地变量(ThreadLocal)传递上下文,适用于传统阻塞式请求处理。
通过 SphU.entry()
显式标记资源,并动态加载规则,避免代码侵入。
代码示例:
public class OrderService {
public void createOrder() {
Entry entry = null;
try {
// 1. 定义资源名称
String resourceName = "createOrder";
// 2. 进入资源保护逻辑
entry = SphU.entry(resourceName);
// 3. 执行业务逻辑
System.out.println("订单创建成功");
} catch (BlockException ex) {
// 4. 限流/熔断处理
System.out.println("系统繁忙,请重试!");
} finally {
// 5. 释放资源
if (entry != null) {
entry.exit();
}
}
}
}
核心逻辑:
• 使用 SphU.entry(resourceName)
手动标记资源入口,通过 try-catch
捕获 BlockException
实现限流或熔断处理。
• 无需任何注解,直接通过代码控制资源保护边界。
通过代码动态加载流量控制规则,支持运行时调整阈值。
规则加载示例:
public class RuleConfigurator {
public static void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("createOrder"); // 资源名称与代码中定义一致
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按 QPS 限流
rule.setCount(100); // 阈值设为 100 QPS
rules.add(rule);
// 动态加载规则
FlowRuleManager.loadRules(rules);
}
}
适用场景:
• 规则可通过外部配置中心(如 Nacos)动态更新,结合 FlowRuleManager
实时生效。
• 规则支持流量控制(QPS/线程数)、熔断降级(异常比例)等多种类型。
同步场景默认通过 ThreadLocal
传递上下文,确保资源调用链的完整性。
实现原理:
• 每个 SphU.entry()
调用会创建 CtEntry
对象,记录当前线程的调用链上下文。
• 同步场景下无需手动管理上下文,Sentinel 自动通过 ThreadLocal
维护状态。
通过 BlockException
分支实现灵活降级策略。
扩展示例:
public class CustomBlockHandler {
public static void handleBlock(BlockException ex, String resourceName) {
// 自定义降级逻辑:记录日志、返回兜底数据等
if (ex instanceof FlowException) {
System.out.println(resourceName + "触发限流,降级处理");
} else if (ex instanceof DegradeException) {
System.out.println(resourceName + "触发熔断,降级处理");
}
}
}
// 在业务代码中调用
catch (BlockException ex) {
CustomBlockHandler.handleBlock(ex, "createOrder");
}
优势:
• 支持按异常类型精细化处理,如区分限流与熔断场景。
通过拦截器或 AOP 自动绑定资源,避免重复编码。
Spring MVC 拦截器示例:
public class SentinelInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String resourceName = request.getRequestURI();
try (Entry entry = SphU.entry(resourceName)) {
return true;
} catch (BlockException ex) {
response.setStatus(429); // 返回 429 状态码
return false;
}
}
}
配置方式:
• 注册拦截器到 Spring 容器,自动保护所有接口。
• 资源名默认为请求路径(如 /api/order
),规则通过控制台或代码动态配置。
场景:电商订单创建接口的 QPS 限流,防止高并发导致数据库压力过大。
代码示例:
@GetMapping("/order/create")
@SentinelResource(value = "createOrder", blockHandler = "handleBlock")
public String createOrder() {
// 同步处理订单创建逻辑
return "订单创建成功";
}
// 限流处理逻辑
public String handleBlock(BlockException ex) {
return "系统繁忙,请稍后再试!";
}
实现原理:
@SentinelResource
标记资源,同步请求到达时由 Sentinel 拦截器统计 QPS,超过阈值触发限流逻辑。场景:针对特定商品 ID 的秒杀请求进行限流。
规则配置(控制台动态设置):
seckill:{productId}
@SentinelResource(value = "seckill", blockHandler = "seckillBlockHandler")
public void seckill(String productId) {
// 处理秒杀逻辑
}
优势:精准限制高频参数请求,避免单点热点导致系统崩溃。
在不使用注解的场景下,Sentinel 通过以下核心机制实现同步资源保护:
SphU.entry()
显式定义资源边界。FlowRuleManager
或 DegradeRuleManager
加载规则。ThreadLocal
维护调用链状态。BlockException
分支和自定义处理器实现。此方案适用于对代码侵入敏感或需深度定制规则的场景(如历史系统改造),兼顾灵活性与性能。
异步场景需通过上下文传递机制保障 Sentinel 规则生效,适用于非阻塞式编程模型(如 WebFlux、CompletableFuture)。
场景:异步调用外部服务(如短信发送)时防止线程池过载。
代码示例:
public void asyncSendSms() {
AsyncEntry entry = null;
try {
entry = SphU.asyncEntry("sendSms"); // 异步资源入口
CompletableFuture.runAsync(() -> {
// 异步发送短信
smsService.send("138xxxx1234", "验证码:1234");
entry.exit(); // 异步任务完成后退出
});
} catch (BlockException e) {
// 限流处理
log.error("短信服务限流", e);
}
}
实现原理:
SphU.asyncEntry
创建 AsyncEntry
对象,异步任务完成后需显式调用 exit()
释放资源。AsyncEntry
维护独立上下文,避免多线程环境下 Context 丢失。场景:WebFlux 非阻塞接口的熔断降级。
代码示例:
@GetMapping("/reactive/api")
@SentinelResource(value = "reactiveApi", fallback = "fallbackMethod")
public Mono<String> reactiveApi() {
return webClient.get()
.uri("/external-service")
.retrieve()
.bodyToMono(String.class)
.onErrorResume(e -> Mono.just("fallback response"));
}
规则配置:
规则持久化
通过集成 Nacos 实现动态规则持久化,避免服务重启后规则丢失:
spring:
cloud:
sentinel:
datasource:
nacos:
server-addr: localhost:8848
data-id: sentinel-rules
规则变更时,Nacos 通知 Sentinel 客户端实时生效。
熔断降级策略
系统自适应保护
根据系统负载(CPU 使用率、平均 RT)动态调整入口流量,防止系统过载:
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(4.0); // CPU load ≥4 时触发限流
rules.add(rule);
SystemRuleManager.loadRules(rules);
维度 | 同步场景 | 异步场景 |
---|---|---|
上下文传递 | 依赖 ThreadLocal ,自动管理 |
需显式使用 AsyncEntry 维护上下文 |
资源释放时机 | 方法执行结束自动释放 | 需在异步回调中手动调用 entry.exit() |
适用框架 | Spring MVC、Dubbo 等传统同步框架 | WebFlux、CompletableFuture 等异步框架 |
性能影响 | 可能阻塞线程,影响吞吐量 | 非阻塞模型更利于高并发场景 |
• 同步场景:优先使用注解 @SentinelResource
,结合热点参数限流保护核心业务。
• 异步场景:需通过 SphU.asyncEntry
显式管理上下文,避免资源泄露。
• 生产建议:结合 Nacos 实现规则动态配置,通过熔断降级和系统保护提升容错能力。
Sentinel 的灵活性与高扩展性使其成为微服务架构下流量控制的理想选择,尤其适合电商秒杀、金融交易等高并发场景。
Spring Cloud Alibaba Sentinel 通过动态流量控制、智能熔断降级和系统自适应保护三大核心能力,成为微服务架构下的“稳定性守护者”。其优势在于动态规则推送、精细化资源管理和多框架兼容性,尤其适合电商、金融等高并发场景。对于已使用 Hystrix 的团队,Sentinel 在实时性和扩展性上的提升(如支持长轮询推送)值得优先迁移。
netty学习专栏
spring-cloud-alibaba使用说明
spring-cloud-alibaba-nacos-discovery使用说明