Sentinel异常处理概述
Sentinel是阿里巴巴开源的分布式系统流量控制组件,主要用于限流、熔断降级、系统负载保护等场景。异常处理是Sentinel的核心功能之一,通过规则配置和回调机制对异常流量或不稳定服务进行管控。
Sentinel异常处理核心机制
流量控制(Flow Control)
通过设定QPS(每秒请求数)或线程数阈值,超出阈值时触发FlowException
异常。规则配置示例:
FlowRule rule = new FlowRule();
rule.setResource("resourceName");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(10); // 阈值QPS=10
FlowRuleManager.loadRules(Collections.singletonList(rule));
熔断降级(Circuit Breaking)
基于异常比例、慢调用比例或异常数触发熔断,抛出DegradeException
。配置示例:
DegradeRule rule = new DegradeRule();
rule.setResource("resourceName");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setCount(5); // 异常数阈值=5
rule.setTimeWindow(10); // 熔断时间10秒
DegradeRuleManager.loadRules(Collections.singletonList(rule));
系统自适应保护(System Rule)
监控系统指标(如CPU使用率、平均RT),触发系统保护时抛出SystemBlockException
。
自定义异常处理逻辑
BlockException处理
通过BlockExceptionHandler
接口实现自定义限流/熔断响应:
public class CustomBlockHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
if (e instanceof FlowException) {
response.setStatus(429);
response.getWriter().print("请求过快,请稍后重试");
} else if (e instanceof DegradeException) {
response.setStatus(503);
response.getWriter().print("服务暂时不可用");
}
}
}
// 注册全局处理器
WebCallbackManager.setBlockHandler(new CustomBlockHandler());
Fallback方法
使用@SentinelResource
注解的fallback
属性处理业务异常:
@SentinelResource(value = "resource", fallback = "fallbackMethod")
public String businessMethod() {
if (someCondition) {
throw new RuntimeException("业务异常");
}
return "success";
}
public String fallbackMethod(Throwable t) {
return "fallback: " + t.getMessage();
}
常见问题排查
- 规则未生效:检查规则是否正确加载到
RuleManager
,资源名称是否匹配。 - 异常统计不准:确保
Tracer.trace(ex)
记录业务异常(非BlockException
)。 - 热点规则失效:参数索引需从0开始,且需启用热点参数限流功能。
最佳实践
- 结合
@ControllerAdvice
全局捕获BlockException
,统一返回格式。 - 在网关层(如Spring Cloud Gateway)集成Sentinel,实现API级别的流控。
- 使用Sentinel Dashboard动态调整规则,避免重启应用。
通过上述机制,Sentinel能够有效保障系统稳定性,避免因流量激增或依赖服务故障导致的雪崩效应。
三种流控规则概述
Sentinel的流量控制(Flow Control)主要通过三种规则实现:直接规则、关联规则和链路规则。每种规则适用于不同场景,控制粒度从资源级到调用链路级逐层细化。
直接规则(直接限流)
定义:针对特定资源直接设置限流阈值(如QPS或线程数),超出阈值则触发流控。
适用场景:单一资源需要独立限流时使用。
配置示例(通过Sentinel Dashboard):
FlowRule rule = new FlowRule();
rule.setResource("resourceName"); // 资源名
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流类型(QPS或线程数)
rule.setCount(10); // 阈值
FlowRuleManager.loadRules(Collections.singletonList(rule));
关键参数:
Grade
:限流维度(FLOW_GRADE_QPS
或FLOW_GRADE_THREAD
)。Count
:阈值数值。
关联规则(关联资源限流)
定义:当关联资源达到阈值时,限制当前资源的访问。例如,支付接口触发限流时,同步限制下单接口。
适用场景:存在资源优先级或依赖关系的场景。
配置示例:
FlowRule rule = new FlowRule();
rule.setResource("primaryResource");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(5);
rule.setRefResource("relatedResource"); // 关联资源名
FlowRuleManager.loadRules(Collections.singletonList(rule));
关键点:
RefResource
需与当前资源存在逻辑关联。- 适用于保护核心资源,避免级联故障。
链路规则(入口限流)
定义:仅统计从特定入口(Entry)进入的流量,并对其限流。
适用场景:需区分流量来源的场景,如限制某个API网关的调用频率。
配置示例:
FlowRule rule = new FlowRule();
rule.setResource("resourceName");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(3);
rule.setLimitApp("entryName"); // 入口名(如Servlet路径)
FlowRuleManager.loadRules(Collections.singletonList(rule));
注意事项:
- 需配合
ContextUtil.enter()
设置入口上下文。 - 链路规则需开启
web-context-unify=false
(默认聚合所有入口)。
规则对比
规则类型 | 控制粒度 | 典型场景 |
---|---|---|
直接规则 | 单资源 | 独立接口限流 |
关联规则 | 跨资源关联 | 保护核心资源,避免级联故障 |
链路规则 | 调用链路入口 | 按来源区分流量(如渠道限流) |
通过组合这三种规则,可灵活应对从单点到链路的复杂限流需求。
Sentinel流控规则中的三种流控效果
1. 快速失败(Quick Fail)
默认的流控效果,当请求超过阈值时直接拒绝请求并抛出FlowException
。适用于对实时性要求高、无需排队等待的场景。可通过以下规则配置:
{
"resource": "testResource",
"limitApp": "default",
"grade": 1, // QPS模式
"count": 10, // 阈值
"strategy": 0, // 直接拒绝
"controlBehavior": 0 // 快速失败
}
2. Warm Up(预热)
通过冷启动方式让系统逐步适应流量增长。适用于系统启动时需要避免冷启动过载的场景,如数据库连接池初始化。配置示例:
{
"controlBehavior": 1, // Warm Up
"warmUpPeriodSec": 10, // 预热时长(秒)
"count": 100 // 最终阈值
}
计算公式:
阈值 = count
× min(当前通过请求数 / warmUpPeriodSec, 1)
3. 排队等待(Throttling)
以恒定速率处理请求,超出阈值的请求进入队列等待。适用于脉冲流量或需要削峰填谷的场景。配置参数:
{
"controlBehavior": 2, // 排队等待
"maxQueueingTimeMs": 500, // 最大等待时间(毫秒)
"count": 5 // 阈值(请求/秒)
}
处理逻辑:
请求间隔 = 1000 / count
毫秒
超时未处理的请求将被拒绝。
效果对比
- 快速失败:响应时间最短,但可能误杀正常请求。
- Warm Up:避免突发流量击穿系统,但初期吞吐量较低。
- 排队等待:保证流量均匀处理,但会增加平均响应时间。
实际选择需结合业务容忍度和系统性能指标。例如秒杀场景适合快速失败,定时任务调度适合排队等待。
熔断降级
Sentinel熔断规则的熔断策略
Sentinel的熔断策略通过规则配置实现,主要包括以下三种熔断策略:
慢调用比例(SlowRequestRatio)
以慢调用比例作为触发熔断的条件。当请求的响应时间超过设定阈值(RT)时,该请求被判定为慢请求。当单位统计时长内慢调用比例超过阈值,且请求数达到最小请求数时触发熔断。
// 示例配置
Rule rule = new DegradeRule("resourceName")
.setGrade(RuleConstant.DEGRADE_GRADE_RT) // 熔断策略为慢调用比例
.setCount(500) // 响应时间阈值500ms
.setTimeWindow(10) // 熔断恢复时间10秒
.setRtSlowRequestAmount(5) // 最小请求数
.setSlowRatioThreshold(0.5); // 慢调用比例阈值
异常比例(ErrorRatio)
当单位统计时长内异常请求比例超过阈值,且请求数达到最小请求数时触发熔断。适用于处理不稳定的服务或依赖。
// 示例配置
Rule rule = new DegradeRule("resourceName")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
.setCount(0.5) // 异常比例阈值50%
.setTimeWindow(10)
.setMinRequestAmount(10); // 最小请求数
异常数(ErrorCount)
当单位统计时长内异常数超过阈值时触发熔断。适用于需要精确控制异常数量的场景。
// 示例配置
Rule rule = new DegradeRule("resourceName")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
.setCount(10) // 异常数阈值
.setTimeWindow(10);
熔断恢复机制
熔断触发后会进入休眠期(timeWindow),在此期间所有请求会被快速失败。休眠期结束后,Sentinel会尝试放行一个请求进行探测:
- 若请求成功,结束熔断状态。
- 若请求失败,继续保持熔断状态。
高级配置参数
统计时长(statIntervalMs)
默认1000ms,用于设置熔断策略的统计时间窗口。较短的统计时长能更快响应系统变化,但可能增加误判风险。
最小请求数(minRequestAmount)
触发熔断的最小请求数门槛。避免在低流量时因偶然错误触发熔断。
熔断时长(timeWindow)
熔断触发后的持续时间,单位秒。可通过设置不同的时间窗口实现阶梯式恢复。
热点规则概述
Sentinel热点规则(Hotspot Rule)用于识别和控制系统中高频访问的热点参数,防止因热点参数引发的系统过载或崩溃。热点参数通常指短时间内被大量请求访问的特定资源,如商品ID、用户ID等。
热点规则配置参数
热点规则配置需关注以下核心参数:
resource
:资源名称,标识规则作用的接口或方法。paramIdx
:热点参数索引,表示参数在方法参数列表中的位置(从0开始)。count
:阈值,单位时间内允许的请求次数。durationSec
:统计时长(秒),与count
共同构成QPS限制。paramFlowItemList
:针对特定参数值的例外配置(如VIP用户可放宽限制)。
热点规则配置示例
以下是通过Sentinel Dashboard配置热点规则的步骤:
- 登录Sentinel Dashboard,选择左侧菜单的"热点规则"。
- 点击"新增热点规则",填写资源名、参数索引、阈值和统计时长。
- 如需特殊参数值配置,在"高级选项"中添加参数值和对应的独立阈值。
代码示例(Java注解方式):
@SentinelResource(
value = "getUserById",
blockHandler = "handleBlock",
fallback = "handleFallback"
)
public User getUserById(Long id) {
// 业务逻辑
}
热点规则高级特性
参数例外项:允许为特定参数值设置独立阈值。例如,商品ID=1001的QPS限制可设置为500,而其他商品ID限制为100。
集群模式支持:通过配置clusterMode
和clusterConfig
,可将热点规则应用于集群环境,统一管控所有节点的流量。
自适应限流:结合Sentinel的滑动窗口统计和令牌桶算法,热点规则可动态调整限流阈值,避免固定阈值导致的资源浪费或突发流量问题。
热点规则最佳实践
- 参数选择:优先选择离散度高且可能引发系统瓶颈的参数(如主键ID)。
- 阈值设定:通过压测获取系统实际承载能力,避免主观设置。
- 监控对接:结合Sentinel实时监控和日志系统,及时发现热点变化。
- 动态调整:利用Sentinel API动态修改规则,应对突发流量场景。
热点规则是Sentinel精细化流量控制的重要功能,合理使用可显著提升系统稳定性。实际应用中需结合业务场景不断调整优化。