SpringCloudAlibaba-Sentinel

基础概念与环境搭建

能干啥?

流量控制与熔断降级组件,类似Hystrix!

https://user-images.githubusercontent.com/9434884/50505538-2c484880-0aaf-11e9-9ffc-cbaaef20be2b.png

Sentinel学习路线

flowchart TD A[Sentinel学习路线] --> B[基础阶段<br>概念与环境搭建] A --> C[核心阶段<br>流量控制与熔断降级] A --> D[高级阶段<br>高级特性与集成] A --> E[进阶阶段<br>生产实践与原理] B --> B1[核心概念理解] B --> B2[环境搭建与配置] B --> B3[第一个Sentinel应用] C --> C1[流量控制规则] C --> C2[熔断降级策略] C --> C3[控制台使用] D --> D1[热点参数限流] D --> D2[系统自适应保护] D --> D3[与Spring Cloud生态集成] E --> E1[规则持久化] E --> E2[集群流控] E --> E3[源码与贡献]

核心概念理解

  • 资源(Resource):可以是代码中的Java方法、接口,甚至是代码块。
  • 规则(Rule): 定义了资源受到何种保护,包括流量控制规则、熔断降级规则、系统保护规则等。规则可以动态修改并立即生效。
  • 流量控制:其原理包括漏桶算法令牌桶算法,通过限制资源的QPS(每秒查询率)或并发线程数来防止系统被瞬时的流量高峰冲垮,是预防服务雪崩的一种措施。
  • 熔断降级:当资源访问出现大量慢调用或异常时,Sentinel会主动熔断对该资源的访问,避免级联故障,直至资源恢复。这与Hystrix的思路类似,但在实现和功能上存在差异。

常见容错框架对比

特性 Sentinel Hystrix Resilience4j
隔离策略 信号量隔离 线程池/信号量隔离 信号量隔离
熔断降级策略 基于慢调用/异常比例 基于失败比率 基于失败比率
流量整形 支持预热/排队 🚫 🚫
系统自适应 支持 🚫 🚫
控制台 提供开源控制台 需要集成监控组件 需要集成监控组件

环境搭建与配置

  1. 引入Sentinel依赖

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-core</artifactId>
        <version>1.8.6</version>
    </dependency>
    
  2. 下载并启动Sentinel控制台

    • 从GitHub Release页面下载最新的sentinel-dashboard-1.8.6.jar包。
    • 使用命令 java -jar sentinel-dashboard.jar 启动(默认端口8080,用户名/密码均为 sentinel)。
  3. 应用接入控制台:在你的应用程序中配置Sentinel控制台地址,以便上报监控数据和接收规则配置。

    spring:
      cloud:
        sentinel:
          transport:
            dashboard: localhost:8080 # Sentinel控制台地址
    

    由于sentinel控制台采用了懒加载模式,所以要先随机访问一个接口后,然后刷新sentinel控制台网站就可以看到数据了

核心功能实践

流量控制(Flow Control)

流量控制是Sentinel最核心的功能,你需要掌握不同的流控模式和效果。

流控模式

  • 直接失败:超出QPS或线程数阈值直接抛出BlockException。如果是响应快或者要保护下游推荐用QPS,如果是响应慢或者要保护自身推荐用线程阈值
  • 关联模式:当关联的资源达到阈值时,对自身进行限流。常用于读写分离等场景,避免非核心操作拖垮核心业务。A设置关联B资源,则B资源出现流控的时候启用当前设置的流控规则
  • 链路模式:只针对从某个特定入口资源来的流量进行限流。

流控效果

  • Warm Up(预热):让流量缓慢增加,直到达到阈值。适用于突然增加大量流量的冷系统,防止冷系统被压垮。
  • 排队等待:让请求以固定的间隔时间匀速通过,类似漏桶算法,用于处理突发流量但允许请求等待的场景。

熔断(Circuit Breaking)

当系统出现不稳定因素时(如响应时间变长、异常比例升高),熔断降级是重要的自我保护机制。

相比于Hystrix,Sentinel没有半开状态

  • 熔断策略
    • 慢调用比例:当资源的响应时间超过阈值,且慢调用的比例超过设置值时,触发熔断。
    • 异常比例:当资源的异常请求比例超过阈值时,触发熔断。
    • 异常数:当单位时间内资源的异常请求数量超过阈值时,触发熔断。

热点参数限流

用于针对指定资源的参数配置规则,限制高频热点访问

@GetMapping("/hotKey")
@SentinelResource(value = "Resource-hotKey", blockHandler = "defaultBlock")
public CommonResult<User> hotKey(@RequestParam("p1") String p1) {
    User user = new User();
    user.setId(1L);
    user.setAge(18);
    return new CommonResult<>(200, "查询成功, serverPort=" + serverPort, user);
}

private CommonResult<User> defaultBlock(String p1, BlockException ex) {
    log.error("热点key方法");
    User user = User.builder().remark("server port=" + serverPort).build();
    return CommonResult.<User>builder().code(200).message(serverPort + "😭").data(user).build();
}

控制台基于资源名配置

image-20250827140023915

参数索引表示从0开始第几个参数

参数例外项表示参数值为指定值的时候单独配置阈值

降级

@GetMapping("/findById/{id}")
@SentinelResource(value = "Resource-hotKey", fallback = "findByIdFallback", blockHandler = "findByIdBlock")
public CommonResult<User> findById(@PathVariable("id") Long id) {
    if (id > 10) {
        throw new RuntimeException("id不能大于10");
    }
    User user = new User();
    user.setId(id);
    user.setName("yangjun");
    user.setAge(18);
    return new CommonResult<>(200, "查询成功, serverPort=" + serverPort, user);
}

private CommonResult<User> findByIdBlock(Long id, BlockException ex) {
    log.error("热点key方法");
    User user = User.builder().build();
    return CommonResult.<User>builder().code(200).message(serverPort + "出现热点了😭").data(user).build();
}

private CommonResult<User> findByIdFallback(Long id) {
    log.error("服务端降级方法");
    User user = User.builder().build();
    return CommonResult.<User>builder().code(200).message(serverPort + "服务降级了😭").data(user).build();
}

fallback控制java代码异常后兜底方案

blockHandler处理Sentinel平台设置的限流方案

自定义URL配置返回

在Sentinel Dashboard通过资源名配置规则可以在资源名上面自定义blockHandler和fallback来实现自定义返回

但是根据URL配置规则的时候,触发规则会提示Blocked by Sentinel (flow limiting)等,不符合业务规则,可以自定义限流提示,可以把上面的blockHandler抽取单独的方法

@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String message = "访问人数过多😭";
        if (e instanceof FlowException) {
            message = "接口限流了😭";
        } else if (e instanceof DegradeException) {
            message = "服务降级了😭";
        }
        CommonResult<User> result = CommonResult.<User>builder().code(200).message(message).build();
        response.setStatus(500);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(JSONObject.toJSONString(result));
    }
}

规则持久化

默认情况下,在Sentinel控制台配置的规则是存储在内存中的,应用重启后规则会丢失。因此,规则持久化是生产应用的必选项

持久化

PUSH模式

客户端增加依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改配置

spring:
  application:
    name: NACOS-PAYMENT-SERVICE
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        port: 8719 # 默认端口,从8719开始找未被占用的
        dashboard: localhost:8080
      eager: true # 是否饥饿加载。可选,设为 true 则服务启动时即连接 Dashboard
      datasource:
        flow-rule: # 数据源名称,可自定义,如 ds1, flow-rule
          nacos:
            server-addr: localhost:8848
            namespace: '09c27e83-cdbb-4f64-92eb-e585cef7b3d7'
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-flow-rules # 在Nacos中存储规则的DataId,通常以应用名关联
            data-type: json # 规则配置的数据类型
            rule-type: flow # 规则类型:flow(流控), degrade(降级), system(系统), param-flow(热点参数)等:cite[10]
        degrade-rule: # 可以继续配置降级规则的数据源
          nacos:
            server-addr: localhost:8848
            namespace: '09c27e83-cdbb-4f64-92eb-e585cef7b3d7'
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-degrade-rules
            data-type: json
            rule-type: degrade

在nacos创建dataId的配置文件,并指定为json格式,然后在文件中配置规则

[
  {
    "resource": "Resource-flowRid",
    "limitApp": "default",
    "grade": 1,
    "count": 10,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

客户端搭配OpenFeign

feign启用sentinel

feign.sentinel.enabled=true

高级特性

系统自适应保护

Sentinel能够自适应地保护整个系统。它会根据系统的LoadCPU使用率总体平均RT入口QPS并发线程数等几个维度的指标,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

黑白名单控制

根据请求来源(如调用方的应用名称、IP等)判断是否允许该请求通过。

持续学习

  • Slot链:了解Sentinel的工作原理核心——责任链模式的ProcessorSlotChain,它是所有功能(统计、限流、降级等)的实现基础。
  • 源码阅读:从SphU.entry()入口开始,逐步阅读核心槽位(如NodeSelectorSlot, ClusterBuilderSlot, StatisticSlot, FlowSlot, DegradeSlot)的源码。
  • 集群流控:单机流控只能限制单台机器的流量,无法精确控制整个集群的总流量。集群流控结合Token Server和Client,可以解决这个问题,适用于网关限流等场景。集群流控
posted @ 2025-08-28 17:12  一只盐桔鸡  阅读(37)  评论(0)    收藏  举报