【Sentinel学习】

Sentinel异常处理概述

Sentinel是阿里巴巴开源的分布式系统流量控制组件,主要用于限流、熔断降级、系统负载保护等场景。异常处理是Sentinel的核心功能之一,通过规则配置和回调机制对异常流量或不稳定服务进行管控。

Sentinel异常处理核心机制

流量控制(Flow Control)

通过设定QPS(每秒请求数)或线程数阈值,超出阈值时触发FlowException异常。规则配置示例:

java 复制代码
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。配置示例:

java 复制代码
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接口实现自定义限流/熔断响应:

java 复制代码
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属性处理业务异常:

java 复制代码
@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):

java 复制代码
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_QPSFLOW_GRADE_THREAD)。
  • Count:阈值数值。

关联规则(关联资源限流)

定义 :当关联资源达到阈值时,限制当前资源的访问。例如,支付接口触发限流时,同步限制下单接口。
适用场景 :存在资源优先级或依赖关系的场景。
配置示例

java 复制代码
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网关的调用频率。
配置示例

java 复制代码
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。适用于对实时性要求高、无需排队等待的场景。可通过以下规则配置:

java 复制代码
{
  "resource": "testResource",
  "limitApp": "default",
  "grade": 1, // QPS模式
  "count": 10, // 阈值
  "strategy": 0, // 直接拒绝
  "controlBehavior": 0 // 快速失败
}

2. Warm Up(预热)

通过冷启动方式让系统逐步适应流量增长。适用于系统启动时需要避免冷启动过载的场景,如数据库连接池初始化。配置示例:

java 复制代码
{
  "controlBehavior": 1, // Warm Up
  "warmUpPeriodSec": 10, // 预热时长(秒)
  "count": 100 // 最终阈值
}

计算公式:

阈值 = count × min(当前通过请求数 / warmUpPeriodSec, 1)

3. 排队等待(Throttling)

以恒定速率处理请求,超出阈值的请求进入队列等待。适用于脉冲流量或需要削峰填谷的场景。配置参数:

java 复制代码
{
  "controlBehavior": 2, // 排队等待
  "maxQueueingTimeMs": 500, // 最大等待时间(毫秒)
  "count": 5 // 阈值(请求/秒)
}

处理逻辑:

请求间隔 = 1000 / count 毫秒

超时未处理的请求将被拒绝。


效果对比

  • 快速失败:响应时间最短,但可能误杀正常请求。
  • Warm Up:避免突发流量击穿系统,但初期吞吐量较低。
  • 排队等待:保证流量均匀处理,但会增加平均响应时间。

实际选择需结合业务容忍度和系统性能指标。例如秒杀场景适合快速失败,定时任务调度适合排队等待。

熔断降级


Sentinel熔断规则的熔断策略

Sentinel的熔断策略通过规则配置实现,主要包括以下三种熔断策略:

慢调用比例(SlowRequestRatio)

以慢调用比例作为触发熔断的条件。当请求的响应时间超过设定阈值(RT)时,该请求被判定为慢请求。当单位统计时长内慢调用比例超过阈值,且请求数达到最小请求数时触发熔断。

java 复制代码
// 示例配置
Rule rule = new DegradeRule("resourceName")
    .setGrade(RuleConstant.DEGRADE_GRADE_RT)  // 熔断策略为慢调用比例
    .setCount(500)  // 响应时间阈值500ms
    .setTimeWindow(10)  // 熔断恢复时间10秒
    .setRtSlowRequestAmount(5)  // 最小请求数
    .setSlowRatioThreshold(0.5);  // 慢调用比例阈值

异常比例(ErrorRatio)

当单位统计时长内异常请求比例超过阈值,且请求数达到最小请求数时触发熔断。适用于处理不稳定的服务或依赖。

java 复制代码
// 示例配置
Rule rule = new DegradeRule("resourceName")
    .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
    .setCount(0.5)  // 异常比例阈值50%
    .setTimeWindow(10)
    .setMinRequestAmount(10);  // 最小请求数

异常数(ErrorCount)

当单位统计时长内异常数超过阈值时触发熔断。适用于需要精确控制异常数量的场景。

java 复制代码
// 示例配置
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配置热点规则的步骤:

  1. 登录Sentinel Dashboard,选择左侧菜单的"热点规则"。
  2. 点击"新增热点规则",填写资源名、参数索引、阈值和统计时长。
  3. 如需特殊参数值配置,在"高级选项"中添加参数值和对应的独立阈值。

代码示例(Java注解方式):

java 复制代码
@SentinelResource(
    value = "getUserById", 
    blockHandler = "handleBlock",
    fallback = "handleFallback"
)
public User getUserById(Long id) {
    // 业务逻辑
}

热点规则高级特性

参数例外项:允许为特定参数值设置独立阈值。例如,商品ID=1001的QPS限制可设置为500,而其他商品ID限制为100。

集群模式支持 :通过配置clusterModeclusterConfig,可将热点规则应用于集群环境,统一管控所有节点的流量。

自适应限流:结合Sentinel的滑动窗口统计和令牌桶算法,热点规则可动态调整限流阈值,避免固定阈值导致的资源浪费或突发流量问题。

热点规则最佳实践

  • 参数选择:优先选择离散度高且可能引发系统瓶颈的参数(如主键ID)。
  • 阈值设定:通过压测获取系统实际承载能力,避免主观设置。
  • 监控对接:结合Sentinel实时监控和日志系统,及时发现热点变化。
  • 动态调整:利用Sentinel API动态修改规则,应对突发流量场景。

热点规则是Sentinel精细化流量控制的重要功能,合理使用可显著提升系统稳定性。实际应用中需结合业务场景不断调整优化。

相关推荐
tmacfrank2 分钟前
Android 网络全栈攻略(四)—— TCPIP 协议族与 HTTPS 协议
android·网络·https
liulilittle11 分钟前
深度剖析:OPENPPP2 libtcpip 实现原理与架构设计
开发语言·网络·c++·tcp/ip·智能路由器·tcp·通信
cui_win12 分钟前
【内存】Linux 内核优化实战 - net.ipv4.tcp_tw_reuse
linux·网络·tcp/ip
夏天想1 小时前
优化 WebSocket 实现单例连接用于打印【待测试 】
网络·websocket·网络协议
我是小bā吖2 小时前
阿里云服务网格ASM实践
网络·阿里云·云计算·服务发现
吴free3 小时前
mac电脑wireshark快速实现http接口抓包
网络·测试工具·http·wireshark
艾希逐月3 小时前
TCP数据的发送和接收
服务器·网络·tcp/ip
述雾学java4 小时前
Spring Cloud Feign 整合 Sentinel 实现服务降级与熔断保护
java·spring cloud·sentinel
D-海漠6 小时前
Modbus_TCP_V4 客户端
网络