一、为什么需要限流组件?
在分布式系统和微服务架构日益普及的今天,流量控制已经成为保障系统稳定性的核心手段。让我们先看一个真实的生产案例:
1.1 真实案例:某电商平台崩溃事故
2023年双11大促期间,某中型电商平台在秒杀活动开启后5分钟内系统全面崩溃。事后分析发现:
流量峰值:正常QPS约500,秒杀开始瞬间飙升至50000+
系统表现:所有服务实例CPU 100%,内存溢出,数据库连接池耗尽
影响范围:不仅秒杀服务崩溃,连带影响首页、浏览、下单等所有核心功能
直接损失:约300万交易额无法完成,品牌声誉受损

图1:无限流保护的系统架构 - 流量冲击场景
如上图所示,没有限流保护的系统面临多重问题:
① 资源耗尽问题当突发流量到来时,系统会按照"先来先服务"的原则处理请求。流量超出系统承载能力后:
CPU持续高负载,上下文切换频繁
内存快速分配导致GC压力增大,最终OOM
数据库连接池被占满,新请求无法获取连接
② 雪崩效应微服务架构中,服务间存在依赖关系。当下游服务因流量过大而响应缓慢或失败时:
上游服务持有的连接/线程无法释放,资源逐渐耗尽
故障会沿着调用链向上传播,最终导致整个系统崩溃
一个服务的故障可能影响整个业务链路
③ 用户体验恶化
正常用户的请求无法得到及时响应
页面长时间加载或直接报错
用户流失,信任度下降
1.2 传统解决方案的局限性
面对流量冲击,传统方案通常包括:

这些方案要么成本过高,要么效果有限,要么需要大量人力投入。我们需要一个更加智能化、自动化的流量控制解决方案。
二、Sentinel简介
2.1 Sentinel是什么?
Sentinel是阿里巴巴开源的一款面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。

2.2 核心特性
① 丰富的应用场景
秒杀系统:瞬间大流量限流
消息削峰:平滑处理突发流量
熔断降级:保护核心服务不被拖垮
实时监控:全方位流量监控大盘
② 完备的实时监控Sentinel提供实时的监控功能,可以监控:
QPS(每秒查询数)
RT(响应时间)
成功率
拒绝数
③ 广泛的开源生态Sentinel提供与主流框架的整合:
Spring Cloud / Spring Boot
Dubbo
gRPC
RocketMQ
④ 完善的SPI扩展点Sentinel提供简单易用、完善的SPI扩展接口,可以通过实现扩展接口来快速定制逻辑。
三、Sentinel核心原理
3.1 责任链模式设计
Sentinel的核心工作原理基于责任链模式,通过一系列的Slot(槽位)串联成一个处理链。

图3:Sentinel核心工作原理
当请求进入时,会依次经过以下Slot:
① NodeSelectorSlot
负责收集资源的调用路径
构建树状结构的调用链路
为每个资源创建DefaultNode
② ClusterBuilderSlot
构建ClusterNode
统计集群维度某个资源的调用情况
用于存储聚合后的统计信息
③ LogSlot
记录异常日志
便于问题排查和定位
④ StatisticSlot
实时统计指标的Slot
记录秒级、分钟级的指标数据
为后续的规则判断提供数据支撑
⑤ AuthoritySlot
黑白名单控制
基于来源的流量控制
⑥ FlowSlot
流量控制Slot
根据配置的限流规则进行判断
超出阈值则抛出FlowException
⑦ DegradeSlot
熔断降级Slot
根据熔断规则判断是否需要熔断
触发熔断则抛出DegradeException
3.2 核心概念
① 资源(Resource)资源是Sentinel的核心概念,可以是:
Java代码中的一段代码
一个接口
一个方法
java
// 定义资源方式一:使用@SentinelResource注解
@SentinelResource(value = "getUserInfo", blockHandler = "handleBlock")
public User getUserInfo(Long id) {
return userService.getUser(id);
}
// 定义资源方式二:使用try-catch
try (Entry entry = SphU.entry("getUserInfo")) {
return userService.getUser(id);
} catch (BlockException e) {
return handleBlock(e);
}
② 规则(Rule)Sentinel支持多种规则类型:

③ 上下文(Context)Context保存了调用链路的元数据,包括:
入口节点(EntranceNode)
当前节点(CurrentNode)
调用来源(Origin)
四、流量控制详解
4.1 限流流程
Sentinel的限流处理流程如下图所示:

图4:Sentinel限流处理流程
4.2 限流维度
① QPS限流每秒查询数限流,适用于:
API接口限流
防止接口被刷
保护下游服务
java
// QPS限流配置
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("getUserInfo");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS维度
rule.setCount(100); // 每秒最多100个请求
rule.setStrategy(RuleConstant.STRATEGY_DIRECT); // 直接拒绝
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 默认行为
rules.add(rule);
FlowRuleManager.loadRules(rules);
② 线程数限流并发线程数限流,适用于:
业务处理时间长
需要限制并发量的场景
java
// 线程数限流配置
FlowRule rule = new FlowRule();
rule.setResource("processOrder");
rule.setGrade(RuleConstant.FLOW_GRADE_THREAD); // 线程数维度
rule.setCount(10); // 最多10个线程并发处理
4.3 限流策略
① 直接拒绝(Default)默认策略,超出阈值直接拒绝请求:
java
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
// 抛出FlowException: Blocked by Sentinel (flow limiting)
② Warm Up(预热)从初始阈值缓慢上升到最大阈值:
java
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
rule.setCount(100); // 最大阈值
rule.setWarmUpPeriodSec(10); // 预热时长10秒
// 实际效果:前10秒从 100/3 ≈ 33 逐渐增加到100
适用于:
秒杀系统预热
缓存预热
系统启动阶段流量控制
③ 排队等待(Throttling)请求在队列中排队,超时则拒绝:
java
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
rule.setCount(100); // 每秒100个请求
rule.setMaxQueueingTimeMs(500); // 最大排队等待时间500ms
适用于:
消息削峰填谷
请求可以适当延迟处理的场景
4.4 关联限流
当关联的资源达到阈值时,对当前资源限流:
java
// 当userLogin资源QPS超过50时,限制getUserInfo
rule.setStrategy(RuleConstant.STRATEGY_RELATE);
rule.setRefResource("userLogin");
rule.setCount(50);
适用场景:
登录接口压力大时,限制其他非核心接口
支付接口压力大时,限制下单接口
五、熔断降级详解
5.1 熔断机制
熔断器模式(Circuit Breaker Pattern)是一种保护性设计模式,Sentinel实现了完整的熔断降级机制。

图5:Sentinel熔断降级机制
熔断器有三种状态:
① Closed(关闭状态)
正常状态,请求正常通过
监控失败率和响应时间
异常达到阈值时,转换为Open状态
② Open(开启状态)
熔断状态,直接拒绝所有请求
持续熔断时长(timeWindow)结束后进入Half-Open状态
③ Half-Open(半开状态)
探测状态,允许部分请求通过
如果请求成功,说明服务已恢复,转为Closed状态
如果请求失败,说明服务仍未恢复,转回Open状态
5.2 熔断策略
① 慢调用比例(SLOW_REQUEST_RATIO)
当资源的响应时间超过最大RT时,被标记为慢调用。慢调用比例超过阈值时触发熔断:
java
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("orderService");
rule.setGrade(RuleConstant.DEGRADE_GRADE_SLOW_REQUEST_RATIO);
rule.setCount(500); // 慢调用阈值:RT > 500ms
rule.setSlowRatioThreshold(0.5); // 慢调用比例阈值:50%
rule.setTimeWindow(10); // 熔断时长:10秒
rule.setMinRequestAmount(5); // 最小请求数:5
rule.setStatIntervalMs(1000); // 统计时长:1秒
rules.add(rule);
DegradeRuleManager.loadRules(rules);
② 异常比例(EXCEPTION_RATIO)
当资源的异常比例超过阈值时触发熔断:
java
DegradeRule rule = new DegradeRule();
rule.setResource("paymentService");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setCount(0.5); // 异常比例阈值:50%
rule.setTimeWindow(10); // 熔断时长:10秒
rule.setMinRequestAmount(5); // 最小请求数:5
③ 异常数(EXCEPTION_COUNT)
当资源的异常数超过阈值时触发熔断:
java
DegradeRule rule = new DegradeRule();
rule.setResource("smsService");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setCount(10); // 异常数阈值:10个
rule.setTimeWindow(10); // 熔断时长:10秒
rule.setMinRequestAmount(5); // 最小请求数:5
5.3 降级处理
当请求被限流或熔断时,需要进行降级处理:
java
@SentinelResource(
value = "getUserInfo",
blockHandler = "handleBlock", // 限流/熔断时的处理
fallback = "handleFallback" // 异常时的处理
)
public User getUserInfo(Long id) {
return userService.getUser(id);
}
// 限流/熔断处理
public User handleBlock(Long id, BlockException e) {
// 返回默认值或缓存数据
return User.getDefaultUser();
}
// 异常处理
public User handleFallback(Long id, Throwable e) {
log.error("获取用户信息异常", e);
return User.getDefaultUser();
}
六、生产实战案例
6.1 电商秒杀系统
以下是一个电商秒杀系统使用Sentinel的完整案例:

图6:生产实战:电商秒杀系统Sentinel应用架构
场景描述:
正常流量:约2000 QPS
秒杀流量:峰值可达50000+ QPS
核心需求:保护库存服务不被击垮
配置方案:
java
@Configuration
publicclass SentinelConfig {
@PostConstruct
public void initRules() {
initSeckillFlowRules();
initOrderDegradeRules();
initStockFlowRules();
}
/**
* 秒杀接口限流规则
*/
private void initSeckillFlowRules() {
List<FlowRule> rules = new ArrayList<>();
// 用户维度限流
FlowRule userRule = new FlowRule();
userRule.setResource("seckill:userId");
userRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
userRule.setCount(5); // 单用户每秒最多5次请求
userRule.setParamIdx(0); // 第一个参数作为userId
rules.add(userRule);
// 接口维度限流
FlowRule apiRule = new FlowRule();
apiRule.setResource("/api/seckill/doSeckill");
apiRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
apiRule.setCount(10000); // 接口整体限制10000 QPS
apiRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
apiRule.setWarmUpPeriodSec(10); // 10秒预热
rules.add(apiRule);
FlowRuleManager.loadRules(rules);
}
/**
* 订单服务熔断规则
*/
private void initOrderDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("orderService:createOrder");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setCount(0.3); // 异常比例30%
rule.setTimeWindow(10); // 熔断10秒
rule.setMinRequestAmount(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
/**
* 库存服务限流规则
*/
private void initStockFlowRules() {
List<FlowRule> rules = new ArrayList<>();
// 线程数限流,保护数据库
FlowRule rule = new FlowRule();
rule.setResource("stockService:decreaseStock");
rule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
rule.setCount(100); // 最多100个线程同时操作
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
核心接口实现:
java
@RestController
@RequestMapping("/api/seckill")
publicclass SeckillController {
@Autowired
private SeckillService seckillService;
/**
* 秒杀接口
*/
@PostMapping("/doSeckill")
@SentinelResource(
value = "seckill:doSeckill",
blockHandler = "handleBlock",
fallback = "handleFallback"
)
public Result doSeckill(@RequestParam Long userId,
@RequestParam Long goodsId) {
try {
boolean success = seckillService.doSeckill(userId, goodsId);
return success ? Result.success("秒杀成功") : Result.error("秒杀失败");
} catch (Exception e) {
log.error("秒杀异常", e);
return Result.error("系统繁忙,请稍后重试");
}
}
/**
* 限流处理
*/
public Result handleBlock(Long userId, Long goodsId, BlockException e) {
if (e instanceof FlowException) {
return Result.error("当前请求过多,请稍后再试");
} elseif (e instanceof DegradeException) {
return Result.error("服务暂时不可用,请稍后再试");
}
return Result.error("系统繁忙");
}
/**
* 异常处理
*/
public Result handleFallback(Long userId, Long goodsId, Throwable e) {
log.error("秒杀异常: userId={}, goodsId={}", userId, goodsId, e);
return Result.error("系统异常,请稍后重试");
}
}
@Service
publicclass SeckillServiceImpl implements SeckillService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StockService stockService;
@Autowired
private OrderService orderService;
@Override
@SentinelResource(
value = "seckill:doSeckill:inner",
blockHandler = "handleBlock"
)
public boolean doSeckill(Long userId, Long goodsId) {
// 1. 校验用户是否重复购买
String key = "seckill:user:" + userId + ":goods:" + goodsId;
Boolean isBought = redisTemplate.hasKey(key);
if (Boolean.TRUE.equals(isBought)) {
thrownew BusinessException("您已经参与过此秒杀活动");
}
// 2. 预扣减库存
Long stock = redisTemplate.opsForValue().decrement("seckill:stock:" + goodsId);
if (stock == null || stock < 0) {
redisTemplate.opsForValue().increment("seckill:stock:" + goodsId);
thrownew BusinessException("库存不足");
}
// 3. 创建订单(可能触发熔断)
try {
Order order = orderService.createOrder(userId, goodsId);
// 标记用户已购买
redisTemplate.opsForValue().set(key, "1", 24, TimeUnit.HOURS);
returntrue;
} catch (DegradeException e) {
// 订单服务熔断,回滚库存
redisTemplate.opsForValue().increment("seckill:stock:" + goodsId);
returnfalse;
}
}
public boolean handleBlock(Long userId, Long goodsId, BlockException e) {
log.warn("秒杀请求被限流: userId={}, goodsId={}", userId, goodsId);
returnfalse;
}
}
监控效果:
接口QPS被控制在10000左右
库存服务线程数不超过100
订单服务异常时自动熔断,不影响其他服务
系统整体可用性达到99.95%
6.2 第三方API调用保护
调用外部接口时,使用Sentinel进行保护:
java
@Service
publicclass ThirdPartyServiceImpl {
/**
* 调用第三方支付接口
*/
@SentinelResource(
value = "thirdParty:payment",
blockHandler = "handleBlock",
fallback = "handleFallback",
fallbackClass = ThirdPartyFallback.class
)
public PaymentResult payment(PaymentRequest request) {
try {
// 调用第三方支付接口
return thirdPartyClient.payment(request);
} catch (Exception e) {
thrownew ThirdPartyException("支付接口调用失败", e);
}
}
public PaymentResult handleBlock(PaymentRequest request, BlockException e) {
// 返回默认结果,后续异步重试
return PaymentResult.pending();
}
}
/**
* 降级处理类
*/
publicclass ThirdPartyFallback {
public static PaymentResult handleFallback(PaymentRequest request, Throwable e) {
log.error("支付接口异常,使用降级逻辑", e);
// 返回降级结果,走人工处理流程
return PaymentResult.manual();
}
}
@Configuration
publicclass ThirdPartySentinelConfig {
@PostConstruct
public void initRules() {
// 慢调用熔断
DegradeRule slowRule = new DegradeRule();
slowRule.setResource("thirdParty:payment");
slowRule.setGrade(RuleConstant.DEGRADE_GRADE_SLOW_REQUEST_RATIO);
slowRule.setCount(1000); // RT > 1秒
slowRule.setSlowRatioThreshold(0.5); // 50%慢调用
slowRule.setTimeWindow(30); // 熔断30秒
slowRule.setMinRequestAmount(5);
// 异常比例熔断
DegradeRule exceptionRule = new DegradeRule();
exceptionRule.setResource("thirdParty:payment");
exceptionRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
exceptionRule.setCount(0.3); // 30%异常
exceptionRule.setTimeWindow(30);
exceptionRule.setMinRequestAmount(5);
DegradeRuleManager.loadRules(Arrays.asList(slowRule, exceptionRule));
}
}
6.3 系统自适应保护
Sentinel提供了系统自适应保护规则,根据系统的负载情况自动调整:
java
@Configuration
publicclass SystemProtectConfig {
@PostConstruct
public void initSystemRules() {
List<SystemRule> rules = new ArrayList<>();
// CPU使用率保护
SystemRule cpuRule = new SystemRule();
cpuRule.setHighestSystemLoad(0.8); // CPU使用率超过80%时触发
rules.add(cpuRule);
// 平均RT保护
SystemRule rtRule = new SystemRule();
rtRule.setAvgRt(1000); // 平均RT超过1000ms时触发
rules.add(rtRule);
// 并发线程数保护
SystemRule threadRule = new SystemRule();
threadRule.setMaxThread(500); // 并发线程超过500时触发
rules.add(threadRule);
// 入口QPS保护
SystemRule qpsRule = new SystemRule();
qpsRule.setQps(10000); // QPS超过10000时触发
rules.add(qpsRule);
SystemRuleManager.loadRules(rules);
}
}
七、Sentinel Dashboard使用
7.1 Dashboard部署
java
# 下载Dashboard
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
# 启动Dashboard
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard \
-jar sentinel-dashboard-1.8.6.jar
7.2 客户端配置
java
# application.yml
spring:
application:
name:sentinel-demo
cloud:
sentinel:
transport:
dashboard:localhost:8080
port:8719
eager:true
datasource:
flow:
type:file
file:classpath:sentinel-flow.json
degrade:
type:file
file:classpath:sentinel-degrade.json
7.3 Dashboard功能
Dashboard提供了以下功能:
实时监控:查看QPS、RT、成功率等指标
规则配置:动态配置流控规则、熔断规则等
集群流控:配置集群限流
机器列表:查看连接到Dashboard的所有机器
八、总结
Sentinel作为一款成熟的流量控制组件,在微服务架构中发挥着重要作用:
核心价值
流量整形:平滑处理突发流量
服务保障:保护核心服务稳定
实时监控:全方位流量监控
快速失败:避免资源耗尽
适用场景
秒杀/抢购场景
第三方API调用
微服务链路保护
系统自适应保护
通过合理使用Sentinel,可以有效提升系统的稳定性和可用性,让微服务架构更加健壮。
图解














