Alibaba Sentinel 入门教程:从理论到实战
文章目录
- 第一部分:理论篇
- 1. Sentinel 简介
- 2. Sentinel 核心原理
- 2.1 资源与规则
- 2.2 Sentinel 工作主流程
- 2.3 核心类解析
- 3. Sentinel 功能支持与使用流程
- 3.1 流量控制
- 3.2 熔断降级
- 3.3 系统自适应保护
- 3.4 热点参数限流
- 3.5 黑白名单控制
- 3.6 使用流程
- 4. Sentinel 架构
- 4.1 核心库
- 4.2 控制台
- 5. 限流组件对比
- 5.1 Sentinel vs Hystrix vs Resilience4j
- 5.2 各组件特点
- Hystrix
- Resilience4j
- Sentinel
- 6. Sentinel 优缺点
- 6.1 优点
- 6.2 缺点
- 7. 理论篇总结
- 第二部分:实战篇
- 1. Sentinel 本地部署
- 1.1 部署 Sentinel Dashboard
- 1.1.1 下载 Dashboard
- 1.1.2 启动 Dashboard
- 1.1.3 访问 Dashboard
- 1.2 配置开机自启(可选)
- Linux 系统(使用 systemd)
- 2. Spring Boot 接入 Sentinel
- 2.1 添加依赖
- 2.2 配置 Sentinel
- 2.3 定义资源
- 2.3.1 使用 @SentinelResource 注解
- 2.3.2 开启 Sentinel 对 Spring MVC 端点的自动保护
- 2.4 启用 Sentinel 注解支持
- 3. Sentinel 核心功能演示
- 3.1 流量控制(Flow Control)
- 3.1.1 通过 Dashboard 配置流控规则
- 3.1.2 代码方式配置流控规则
- 3.2 熔断降级(Circuit Breaking)
- 3.2.1 通过 Dashboard 配置熔断规则
- 3.2.2 代码方式配置熔断规则
- 3.3 热点参数限流(Hot Spot)
- 3.3.1 使用 @SentinelResource 注解定义热点参数资源
- 3.3.2 通过 Dashboard 配置热点规则
- 3.3.3 代码方式配置热点规则
- 3.4 系统自适应保护(System Adaptive Protection)
- 3.4.1 通过 Dashboard 配置系统规则
- 3.4.2 代码方式配置系统规则
- 4. 规则持久化
- 4.1 基于文件的规则持久化
- 4.2 基于 Nacos 的规则持久化
- 4.3 基于 Consul 的规则持久化
- 5. 实际应用案例
- 5.1 接口限流保护
- 5.2 服务调用保护
- 5.3 网关限流保护
- 6. 最佳实践
- 6.1 合理划分资源
- 6.2 选择合适的限流策略
- 6.3 合理配置熔断规则
- 6.4 规则持久化
- 6.5 监控告警
- 7. 常见问题与解决方案
- 7.1 应用无法注册到 Dashboard
- 7.2 规则不生效
- 7.3 @SentinelResource 注解不生效
- 8. 实战篇总结
- 参考资料
本文尝试入门 Alibaba Sentinel,一个强大的流量控制组件。我们将从理论出发,涵盖其核心原理、功能特性、架构设计以及与其他主流限流组件的对比,然后进入实战环节,详细介绍 Sentinel 的本地部署、与 Spring Boot 的集成方法,并演示其核心功能的使用。
第一部分:理论篇
1. Sentinel 简介
Sentinel 是阿里巴巴开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
- 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 分为两个部分:
- 核心库(Java 客户端):不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard):基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
2. Sentinel 核心原理
2.1 资源与规则
在 Sentinel 中,资源是保护的基本单位,可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。
资源定义的方式主要有几种:
- 通过
SphU.entry("resourceName")
和entry.exit()
方法定义资源 - 通过
@SentinelResource
注解定义资源 - 通过适配器接入(如 Web 适配器、Dubbo 适配器等)
规则是 Sentinel 的核心概念之一,通过规则来指定资源的限流、熔断、系统保护等行为。规则可以动态实时地进行配置和修改,并立即生效。
2.2 Sentinel 工作主流程
在 Sentinel 里面,所有的资源都对应一个资源名称(resourceName
),每次资源调用都会创建一个 Entry
对象。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 SphU
API 显式创建。
Entry 创建的时候,同时也会创建一系列功能插槽(slot chain),这些插槽有不同的职责:
- NodeSelectorSlot:负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
- ClusterBuilderSlot:用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
- StatisticSlot:用于记录、统计不同纬度的 runtime 指标监控信息;
- FlowSlot:用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
- AuthoritySlot:根据配置的黑白名单和调用来源信息,来做黑白名单控制;
- DegradeSlot:通过统计信息以及预设的规则,来做熔断降级;
- SystemSlot:通过系统的状态,例如 load1 等,来控制总的入口流量。
Sentinel 将 ProcessorSlot
作为 SPI 接口进行扩展,使得 Slot Chain 具备了扩展的能力。用户可以自行加入自定义的 slot 并编排 slot 间的顺序,从而可以给 Sentinel 添加自定义的功能。
2.3 核心类解析
Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起。slot chain 其实可以分为两部分:统计数据构建部分(statistic)和判断部分(rule checking)。
主要核心类包括:
- ProcessorSlotChain:Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起
- Context:代表调用链路上下文,贯穿一次调用链路中的所有
Entry
- Entry:每一次资源调用都会创建一个 Entry
- Node:各种统计节点,如 StatisticNode、DefaultNode、ClusterNode、EntranceNode 等
- StatisticSlot:Sentinel 最为重要的类之一,用于根据规则判断结果进行相应的统计操作
3. Sentinel 功能支持与使用流程
3.1 流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。在 Sentinel 中,我们可以通过流控规则来控制系统的 QPS 或并发线程数等指标。
流量控制的方式包括:
- 直接拒绝:当 QPS 超过阈值时,直接拒绝多余的请求
- 冷启动/预热:当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮
- 匀速排队:严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法
3.2 熔断降级
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。
Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。
熔断降级支持的模式:
- 慢调用比例:当单位统计时长内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断
- 异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断
- 异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断
3.3 系统自适应保护
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
3.4 热点参数限流
热点参数限流是一种更细粒度的流量控制,它允许我们针对某个热点参数进行限流,比如针对某个用户 ID 限流。
3.5 黑白名单控制
黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑白名单则请求来源位于黑名单时不通过,其余的请求通过。
3.6 使用流程
Sentinel 的使用流程非常简单,主要包括以下几个步骤:
- 定义资源:通过 API 或注解方式定义资源
- 定义规则:配置规则,包括流控规则、熔断规则、系统规则等
- 检验规则是否生效:通过运行程序并观察监控数据,检验规则是否生效
4. Sentinel 架构
Sentinel 的整体架构分为核心库和控制台两部分:
4.1 核心库
核心库不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
核心库主要负责:
- 定义资源
- 规则管理
- 实时统计
- 规则判断
- 扩展点
4.2 控制台
控制台(Dashboard)主要负责:
- 规则管理:配置规则、查看规则
- 监控展示:查看秒级监控,了解系统实时运行情况
- 机器发现:自动发现应用
5. 限流组件对比
5.1 Sentinel vs Hystrix vs Resilience4j
功能 | Sentinel | Hystrix | Resilience4j |
---|---|---|---|
隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于响应时间、异常比率、异常数等 | 异常比率模式、超时熔断 | 基于异常比率、响应时间 |
实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于 RxJava) | Ring Bit Buffer |
动态规则配置 | 支持多种配置源 | 支持多种数据源 | 有限支持 |
扩展性 | 丰富的 SPI 扩展接口 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
集群流量控制 | 支持 | 不支持 | 不支持 |
流量整形 | 支持预热模式、匀速排队模式等多种复杂场景 | 不支持 | 简单的 Rate Limiter 模式 |
系统自适应保护 | 支持 | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 |
多语言支持 | Java / Go / C++ | Java | Java |
开源社区状态 | 活跃 | 停止维护 | 较活跃 |
5.2 各组件特点
Hystrix
Hystrix 的关注点在于以隔离和熔断为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制。
Hystrix 的资源模型设计上采用了命令模式,将对外部资源的调用和 fallback 逻辑封装成一个命令对象(HystrixCommand/ HystrixObservableCommand),其底层的执行是基于 RxJava 实现的。
Hystrix 的线程池隔离针对不同的资源分别创建不同的线程池,不同服务调用都发生在不同的线程池中,在线程池排队、超时等阻塞情况时可以快速失败。但是,线程池隔离的代价就是线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。
需要注意的是,Netflix 已经宣布 Hystrix 进入维护模式,不再添加新功能,推荐使用 Resilience4j 或 Sentinel。
Resilience4j
Resilience4j 是一个受 Netflix Hystrix 启发的轻量级容错库,但它是为 Java 8 和函数式编程设计的。轻量级,因为库只使用 Vavr,它没有任何其他外部库依赖项。
Resilience4j 提供高阶函数(decorators)来增强任何功能接口、lambda 表达式或方法引用,包括断路器、速率限制器、重试或隔板。可以在任何函数接口、lambda 表达式或方法引用上堆叠多个装饰器。优点是可以选择所需的装饰器,而无需其他任何东西。
Sentinel
Sentinel 的侧重点在于:
- 多样化的流量控制策略,支持预热模式、匀速排队模式等多种复杂场景
- 熔断降级
- 系统负载保护
- 实时监控和控制台
Sentinel 的设计更为简单。相比 Hystrix Command 强依赖隔离规则,Sentinel 的资源定义与规则配置的耦合度更低。Sentinel 并不指定执行模型,也不关注应用是如何执行的。Sentinel 的原则非常简单:根据对应资源配置的规则来为资源执行相应的限流/降级/负载保护策略。
6. Sentinel 优缺点
6.1 优点
- 丰富的应用场景:Sentinel 提供了多样化的流量控制策略,支持预热模式、匀速排队模式等多种复杂场景,能够满足各种业务需求。
- 完备的实时监控:Sentinel 提供了实时的监控功能,可以在控制台中看到接入应用的单台机器秒级数据,甚至集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供了与 Spring Cloud、Apache Dubbo、gRPC 等框架的整合模块,使得接入变得非常简单。
- 完善的 SPI 扩展机制:Sentinel 提供了简单易用、完善的 SPI 扩展接口,可以通过实现扩展接口来快速地定制逻辑。
- 多语言支持:Sentinel 提供了 Java/Go/C++ 等多语言的原生实现。
- 活跃的社区:Sentinel 拥有活跃的社区,持续更新和维护。
- 阿里巴巴生产环境验证:Sentinel 在阿里巴巴内部经过了大规模的生产环境验证,包括双十一等高并发场景。
6.2 缺点
- 学习曲线:相比于一些简单的限流组件,Sentinel 的功能更加丰富,因此学习曲线可能会更陡峭。
- 配置复杂性:由于功能丰富,Sentinel 的配置相对复杂,需要对各种规则有深入的理解。
- 控制台依赖:虽然核心库不依赖控制台,但要充分发挥 Sentinel 的功能,控制台是必不可少的。
- 规则持久化:默认情况下,规则是存储在内存中的,需要额外配置才能实现规则的持久化。
- 集群限流的复杂性:虽然 Sentinel 支持集群限流,但配置和维护相对复杂。
7. 理论篇总结
Sentinel 作为一个面向分布式服务架构的轻量级高可用流量控制组件,提供了丰富的功能和良好的扩展性,能够满足各种复杂的业务场景。相比于 Hystrix 和 Resilience4j,Sentinel 在流量控制、系统自适应保护、实时监控等方面具有明显的优势。
在选择限流组件时,需要根据具体的业务场景和需求进行选择。如果需要丰富的流量控制策略、系统自适应保护和实时监控,Sentinel 是一个很好的选择;如果更注重轻量级和函数式编程,Resilience4j 可能更适合;而 Hystrix 由于已经进入维护模式,不再推荐使用。
无论选择哪种组件,都需要深入理解其核心原理和使用方法,才能充分发挥其功能,保障系统的稳定性和可用性。
第二部分:实战篇
1. Sentinel 本地部署
1.1 部署 Sentinel Dashboard
Sentinel Dashboard 是 Sentinel 的控制台组件,提供机器发现、监控、规则管理等功能。以下是部署步骤:
1.1.1 下载 Dashboard
首先,从 GitHub 下载最新版本的 Sentinel Dashboard:
https://github.com/alibaba/Sentinel/releases
当前最新的稳定版本是 sentinel-dashboard-1.8.7.jar
。
1.1.2 启动 Dashboard
使用以下命令启动 Sentinel Dashboard:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
参数说明:
-Dserver.port=8080
:指定 Dashboard 的端口号为 8080-Dcsp.sentinel.dashboard.server=localhost:8080
:指定 Dashboard 的地址和端口-Dproject.name=sentinel-dashboard
:指定项目名称
如果需要修改默认的用户名和密码(默认都是 sentinel
),可以添加以下参数:
-Dsentinel.dashboard.auth.username=admin
:设置用户名为 admin-Dsentinel.dashboard.auth.password=123456
:设置密码为 123456
1.1.3 访问 Dashboard
启动成功后,通过浏览器访问:http://localhost:8080
使用默认用户名和密码(都是 sentinel
)登录,或者使用自定义的用户名和密码。
1.2 配置开机自启(可选)
如果需要将 Sentinel Dashboard 设置为开机自启,可以根据不同的操作系统进行配置:
Linux 系统(使用 systemd)
- 创建服务文件:
sudo vim /etc/systemd/system/sentinel-dashboard.service
- 添加以下内容:
[Unit]
Description=Sentinel Dashboard
After=network.target[Service]
Type=simple
User=your_username
ExecStart=/usr/bin/java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar /path/to/sentinel-dashboard.jar
Restart=on-failure[Install]
WantedBy=multi-user.target
- 启用服务:
sudo systemctl daemon-reload
sudo systemctl enable sentinel-dashboard
sudo systemctl start sentinel-dashboard
2. Spring Boot 接入 Sentinel
2.1 添加依赖
在 Spring Boot 项目的 pom.xml
文件中添加 Sentinel 依赖:
<!-- Spring Cloud Alibaba Sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><!-- 引入 Spring Cloud Alibaba 依赖管理 -->
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2022.0.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
注意:请根据的 Spring Boot 版本选择合适的 Spring Cloud Alibaba 版本。例如:
- Spring Boot 3.x 对应 Spring Cloud Alibaba 2022.x.x
- Spring Boot 2.6.x 对应 Spring Cloud Alibaba 2021.x.x
- Spring Boot 2.4.x 对应 Spring Cloud Alibaba 2.2.6.RELEASE
2.2 配置 Sentinel
在 application.yml
或 application.properties
中添加 Sentinel 配置:
spring:application:name: sentinel-democloud:sentinel:transport:# 配置 Sentinel Dashboard 地址dashboard: localhost:8080# 指定应用与 Sentinel Dashboard 通信的端口(默认为 8719)port: 8719# 饥饿加载模式,项目启动时即初始化 Sentineleager: true
2.3 定义资源
在 Spring Boot 中,有多种方式定义 Sentinel 资源:
2.3.1 使用 @SentinelResource 注解
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("/hello")@SentinelResource(value = "hello", blockHandler = "blockHandlerForHello",fallback = "fallbackForHello")public String hello() {return "Hello Sentinel";}// 处理限流或降级public String blockHandlerForHello(BlockException ex) {return "Blocked by Sentinel: " + ex.getClass().getSimpleName();}// 处理业务异常public String fallbackForHello(Throwable t) {return "Fallback: " + t.getMessage();}
}
2.3.2 开启 Sentinel 对 Spring MVC 端点的自动保护
在 application.yml
中添加:
spring:cloud:sentinel:web-context-unify: false
这样,所有的 Spring MVC 端点都会自动作为 Sentinel 资源,资源名为请求路径(如 /hello
)。
2.4 启用 Sentinel 注解支持
在启动类或配置类上添加 @EnableSentinel
注解:
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class SentinelDemoApplication {public static void main(String[] args) {SpringApplication.run(SentinelDemoApplication.class, args);}@Bean@LoadBalanced@SentinelRestTemplatepublic RestTemplate restTemplate() {return new RestTemplate();}
}
3. Sentinel 核心功能演示
3.1 流量控制(Flow Control)
流量控制是 Sentinel 最基本的功能,用于限制资源的访问量,保障系统稳定性。
3.1.1 通过 Dashboard 配置流控规则
- 访问 Sentinel Dashboard
- 选择应用,进入"流控规则"页面
- 点击"新增流控规则"按钮
- 填写规则信息:
- 资源名:要保护的资源名称,如
hello
- 针对来源:默认为
default
,表示不区分调用来源 - 阈值类型:选择 QPS 或线程数
- 单机阈值:设置限流阈值,如 QPS 为 5
- 流控模式:直接、关联或链路
- 流控效果:快速失败、Warm Up 或排队等待
- 资源名:要保护的资源名称,如
- 点击"新增"按钮保存规则
3.1.2 代码方式配置流控规则
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;@Component
public class SentinelRuleConfig {@PostConstructpublic void initFlowRules() {List<FlowRule> rules = new ArrayList<>();// 创建流控规则FlowRule rule = new FlowRule();// 设置资源名rule.setResource("hello");// 设置限流阈值类型为 QPSrule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置 QPS 阈值为 5rule.setCount(5);rules.add(rule);// 加载规则FlowRuleManager.loadRules(rules);}
}
3.2 熔断降级(Circuit Breaking)
熔断降级是对调用链路中不稳定的资源进行熔断保护,防止级联故障。
3.2.1 通过 Dashboard 配置熔断规则
- 访问 Sentinel Dashboard
- 选择应用,进入"熔断规则"页面
- 点击"新增熔断规则"按钮
- 填写规则信息:
- 资源名:要保护的资源名称
- 熔断策略:慢调用比例、异常比例或异常数
- 最小请求数:触发熔断的最小请求数
- 统计时长:统计时间窗口,单位为 ms
- 熔断时长:熔断持续时间,单位为 s
- 慢调用比例阈值:慢调用占比超过该值触发熔断(仅慢调用比例模式)
- 异常比例阈值:异常请求占比超过该值触发熔断(仅异常比例模式)
- 异常数阈值:异常请求数超过该值触发熔断(仅异常数模式)
- 点击"新增"按钮保存规则
3.2.2 代码方式配置熔断规则
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;@Component
public class SentinelDegradeConfig {@PostConstructpublic void initDegradeRules() {List<DegradeRule> rules = new ArrayList<>();// 创建熔断规则DegradeRule rule = new DegradeRule();// 设置资源名rule.setResource("hello");// 设置熔断策略为异常比例rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);// 设置异常比例阈值,取值范围 [0.0, 1.0]rule.setCount(0.5);// 设置最小请求数rule.setMinRequestAmount(5);// 设置统计时长,单位为 msrule.setStatIntervalMs(1000);// 设置熔断时长,单位为 srule.setTimeWindow(10);rules.add(rule);// 加载规则DegradeRuleManager.loadRules(rules);}
}
3.3 热点参数限流(Hot Spot)
热点参数限流是一种更细粒度的流量控制,它允许我们针对某个热点参数进行限流。
3.3.1 使用 @SentinelResource 注解定义热点参数资源
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HotSpotController {@GetMapping("/product")@SentinelResource(value = "getProduct", blockHandler = "getProductBlockHandler")public String getProduct(@RequestParam Long productId) {return "Product info: " + productId;}public String getProductBlockHandler(Long productId, BlockException ex) {return "Blocked by hot spot rule: " + productId;}
}
3.3.2 通过 Dashboard 配置热点规则
- 访问 Sentinel Dashboard
- 选择应用,进入"热点规则"页面
- 点击"新增热点规则"按钮
- 填写规则信息:
- 资源名:要保护的资源名称,如
getProduct
- 参数索引:参数在方法参数列表中的索引,从 0 开始,如
0
表示第一个参数 - 单机阈值:限流阈值
- 统计窗口时长:统计时间窗口,单位为秒
- 资源名:要保护的资源名称,如
- 点击"新增"按钮保存规则
3.3.3 代码方式配置热点规则
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;@Component
public class SentinelHotSpotConfig {@PostConstructpublic void initParamFlowRules() {List<ParamFlowRule> rules = new ArrayList<>();// 创建热点参数规则ParamFlowRule rule = new ParamFlowRule();// 设置资源名rule.setResource("getProduct");// 设置限流模式为 QPSrule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置参数索引rule.setParamIdx(0);// 设置限流阈值rule.setCount(5);// 特例配置:对特定参数值单独设置阈值ParamFlowItem item = new ParamFlowItem();// 设置参数值item.setObject(String.valueOf(1));// 设置特例阈值item.setCount(10);// 设置限流模式为 QPSitem.setClassType(String.class.getName());rule.setParamFlowItemList(Collections.singletonList(item));rules.add(rule);// 加载规则ParamFlowRuleManager.loadRules(rules);}
}
3.4 系统自适应保护(System Adaptive Protection)
系统自适应保护从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率等指标,让系统的入口流量和系统的负载达到一个平衡。
3.4.1 通过 Dashboard 配置系统规则
- 访问 Sentinel Dashboard
- 选择应用,进入"系统规则"页面
- 点击"新增系统规则"按钮
- 填写规则信息:
- 系统 Load:当系统 load1 超过阈值,触发系统保护
- CPU 使用率:当系统 CPU 使用率超过阈值,触发系统保护
- 平均 RT:当单台机器所有入口流量的平均 RT 达到阈值,触发系统保护
- 并发线程数:当单台机器所有入口流量的并发线程数达到阈值,触发系统保护
- 入口 QPS:当单台机器所有入口流量的 QPS 达到阈值,触发系统保护
- 点击"新增"按钮保存规则
3.4.2 代码方式配置系统规则
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;@Component
public class SentinelSystemConfig {@PostConstructpublic void initSystemRules() {List<SystemRule> rules = new ArrayList<>();// 创建系统规则SystemRule rule = new SystemRule();// 设置 load 阈值rule.setHighestSystemLoad(3.0);// 设置 CPU 使用率阈值rule.setHighestCpuUsage(0.6);// 设置平均 RT 阈值,单位是毫秒rule.setAvgRt(500);// 设置并发线程数阈值rule.setMaxThread(200);// 设置入口 QPS 阈值rule.setQps(300);rules.add(rule);// 加载规则SystemRuleManager.loadRules(rules);}
}
4. 规则持久化
默认情况下,Sentinel 的规则是存储在内存中的,应用重启后规则会丢失。为了解决这个问题,Sentinel 提供了动态规则源支持,可以将规则持久化到外部存储。
4.1 基于文件的规则持久化
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.File;
import java.util.List;@Component
public class FileDataSourceInit {@PostConstructpublic void init() throws Exception {String ruleDir = System.getProperty("user.home") + "/sentinel/rules";String flowRulePath = ruleDir + "/flow-rule.json";// 创建目录File dir = new File(ruleDir);if (!dir.exists()) {dir.mkdirs();}// 创建文件数据源ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(flowRulePath,source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));// 注册到 FlowRuleManagerFlowRuleManager.register2Property(flowRuleDataSource.getProperty());}
}
4.2 基于 Nacos 的规则持久化
首先,添加 Nacos 数据源依赖:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
然后,在 application.yml
中配置 Nacos 数据源:
spring:cloud:sentinel:datasource:flow:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-flow-rulesgroupId: SENTINEL_GROUPrule-type: flowdegrade:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUPrule-type: degrade
4.3 基于 Consul 的规则持久化
首先,添加 Consul 数据源依赖:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-consul</artifactId><version>1.8.6</version>
</dependency>
然后,在 application.yml
中配置 Consul 数据源:
spring:cloud:sentinel:datasource:flow:consul:host: localhostport: 8500rule-key: sentinel_flow_ruledata-type: jsonrule-type: flow
在 Consul 中添加规则配置:
[{"resource": "/hello","limitApp": "default","grade": 1,"count": 5,"strategy": 0,"controlBehavior": 0}
]
5. 实际应用案例
5.1 接口限流保护
以下是一个完整的接口限流保护示例:
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api")
public class ApiController {@GetMapping("/test")@SentinelResource(value = "apiTest", blockHandler = "blockHandlerForApiTest",fallback = "fallbackForApiTest")public String apiTest() {// 模拟业务逻辑return "API test success";}// 处理限流或降级public String blockHandlerForApiTest(BlockException ex) {return "API request blocked: " + ex.getClass().getSimpleName();}// 处理业务异常public String fallbackForApiTest(Throwable t) {return "API request failed: " + t.getMessage();}
}
5.2 服务调用保护
使用 @SentinelRestTemplate
注解保护 RestTemplate 调用:
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Bean@SentinelRestTemplate(blockHandler = "handleBlock", fallback = "handleFallback")public RestTemplate restTemplate() {return new RestTemplate();}// 处理限流或降级public static String handleBlock(String url, Exception ex) {return "RestTemplate request blocked: " + url;}// 处理业务异常public static String handleFallback(String url, Throwable t) {return "RestTemplate request failed: " + url;}
}
5.3 网关限流保护
如果使用 Spring Cloud Gateway,可以添加 Sentinel 网关限流支持:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
在 application.yml
中配置:
spring:cloud:gateway:routes:- id: service-routeuri: lb://service-namepredicates:- Path=/service/**sentinel:scg:fallback:mode: responseresponse-body: '{"code":429,"message":"Too many requests"}'
6. 最佳实践
6.1 合理划分资源
资源是 Sentinel 的核心概念,合理划分资源是使用 Sentinel 的基础。建议按照以下原则划分资源:
- 按照业务功能划分资源,而不是技术实现
- 保持资源粒度的一致性,不要过粗或过细
- 为资源命名时使用有意义的名称,便于识别和管理
6.2 选择合适的限流策略
Sentinel 提供了多种限流策略,应根据业务场景选择合适的策略:
- 直接拒绝:适用于大部分场景,直接拒绝超出阈值的请求
- 冷启动(Warm Up):适用于系统刚启动或流量突增的场景,让通过的流量缓慢增加
- 匀速排队:适用于请求需要严格按照时间间隔处理的场景
6.3 合理配置熔断规则
熔断规则的配置应考虑以下因素:
- 最小请求数:设置合理的最小请求数,避免因为少量请求就触发熔断
- 统计时长:根据业务特点设置合适的统计窗口
- 熔断时长:根据故障恢复时间设置合适的熔断时长
- 阈值:根据系统容量和业务容忍度设置合适的阈值
6.4 规则持久化
在生产环境中,建议将规则持久化到外部存储,如 Nacos、ZooKeeper、Apollo 等,避免应用重启后规则丢失。
6.5 监控告警
结合 Sentinel 的监控功能,建立完善的监控告警机制,及时发现和处理系统异常。
7. 常见问题与解决方案
7.1 应用无法注册到 Dashboard
可能的原因和解决方案:
- 检查 Dashboard 地址配置是否正确
- 确保应用有访问量,Sentinel 会在首次调用时初始化
- 检查网络连接,确保应用可以访问 Dashboard
- 查看日志
${user.home}/logs/csp/sentinel-record.log.xxx
排查问题
7.2 规则不生效
可能的原因和解决方案:
- 检查资源名称是否正确
- 确保规则已正确加载
- 检查是否有冲突的规则
- 查看日志排查问题
7.3 @SentinelResource 注解不生效
可能的原因和解决方案:
- 确保已启用 Sentinel 注解支持(
@EnableSentinel
) - 确保方法是 public 的
- 确保不是内部方法调用(内部方法调用不会触发 AOP)
- 检查 blockHandler 和 fallback 方法的签名是否正确
8. 实战篇总结
本实战篇详细介绍了 Sentinel 的本地部署、Spring Boot 接入方法以及核心功能的使用。通过学习和实践,应该能够:
- 部署和配置 Sentinel Dashboard
- 将 Sentinel 集成到 Spring Boot 应用中
- 使用 Sentinel 的流量控制、熔断降级、热点参数限流和系统自适应保护功能
- 实现规则持久化
- 应用 Sentinel 最佳实践
Sentinel 作为一个功能强大的流量控制组件,能够有效保障应用的稳定性和可用性。希望本教程能够帮助快速上手 Sentinel,并在实际项目中发挥其价值。
参考资料
- Sentinel GitHub Wiki: https://github.com/alibaba/Sentinel/wiki
- Sentinel 介绍: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
- Sentinel 工作原理: https://github.com/alibaba/Sentinel/wiki/%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86
- Sentinel 工作主流程: https://github.com/alibaba/Sentinel/wiki/Sentinel%E5%B7%A5%E4%BD%9C%E4%B8%BB%E6%B5%81%E7%A8%8B
- Sentinel 核心类解析: https://github.com/alibaba/Sentinel/wiki/Sentinel-%E6%A0%B8%E5%BF%83%E7%B1%BB%E8%A7%A3%E6%9E%90
- 常用限流降级组件对比: https://github.com/alibaba/Sentinel/wiki/%E5%B8%B8%E7%94%A8%E9%99%90%E6%B5%81%E9%99%8D%E7%BA%A7%E7%BB%84%E4%BB%B6%E5%AF%B9%E6%AF%94
- Sentinel 控制台: https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0
- CSDN - 限流降级组件Sentinel、Hystrix、Resilience4j对比: https://blog.csdn.net/krauser1991/article/details/120293507
- CSDN - SpringBoot 3.1.7 集成Sentinel: https://blog.csdn.net/u010887012/article/details/135694628
相关文章:
Alibaba Sentinel 入门教程:从理论到实战
文章目录 第一部分:理论篇1. Sentinel 简介2. Sentinel 核心原理2.1 资源与规则2.2 Sentinel 工作主流程2.3 核心类解析 3. Sentinel 功能支持与使用流程3.1 流量控制3.2 熔断降级3.3 系统自适应保护3.4 热点参数限流3.5 黑白名单控制3.6 使用流程 4. Sentinel 架构…...
2.3 TypeScript 非空断言操作符(后缀 !)详解
在 TypeScript 中,当你开启了严格的空值检查(strictNullChecks)后,变量如果可能是 null 或 undefined,就必须在使用前进行显式的判断。为了在某些场景下简化代码,TypeScript 提供了非空断言操作符ÿ…...

【菜狗work前端】小程序加if判断时不及时刷新 vs Web
零、前提: 实现input输入数字不大于10000(需要配合typenumber,maxlength5,这里没写) 一、探究代码: <input v-model"model1" input"changeModel1" placeholder"请输入拒收件…...
01 NLP的发展历程和挑战
1.人工智能行业介绍 ANI、AGI、ASI 以下是弱人工智能(ANI)、强人工智能(AGI)和超强人工智能(ASI)的对比表格: 类型定义当前状态弱人工智能(ANI)专注于特定任务&#x…...

TCP 三次握手:详解与原理
无图、长文警告!!!! 文章目录 一、引言二、TCP 三次握手的过程(一)第一次握手:SYN(同步序列号)(二)第二次握手:SYN-ACK(同…...

LabVIEW累加器标签通道
主要展示了 Accumulator Tag 通道的使用,通过三个并行运行的循环模拟不同数值的多个随机序列,分别以不同频率向累加器写入数值,右侧循环每秒读取累加器值,同时可切换查看每秒内每次事件的平均值,用于演示多线程数据交互…...
在 Unity 中,Start 方法直接设置 RectTransform 的位置,时出现问题,与预计位置不匹配。
改动之前的源代码:发现组件的位置,与设计的位置不一样,但是如果把这段代码,交给一个按钮按下回调,就不会出现问题。 void Start(){//初始化Text 行//读取配置文件;StaticDataObj obj Resources.Load<St…...

永磁同步电机控制算法--IP调节器
一、基本原理 在电机控制领域,现今普遍使用的是比例-积分(PI)控制器。然而,PI控制器有一些缺点,可能会在某些应用中产生一些问题,例如:一个非常快的响应,也同时具有过大的超调量。虽然设计PI控制器时,可以…...

Ubuntu 25.04 锁屏不能远程连接的解决方案
最近安装了一个 Ubuntu 25.04,偶然发现可以通过 windows 自带的 rdp 远程工具进行连接,内心狂喜。此外,还支持启动 VNC 协议,也就是默认支持了 rdp 和 vnc 连接。 看了以下,ubuntu 在用户级别下创建了一个远程桌面服务…...

Java 自动装箱和拆箱还有包装类的缓存问题
自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5 后, Java 引入了自动装箱(autoboxing)/拆箱(unboxing)。 自动装箱: 基本类型的数据处于需要对象的环境中时,会自动转为“对象”。 我们以 Integer 为例:…...

java-jdk8新特性Stream流
一、Stream流 是专业用于对集合或者数组进行便捷操作的。 1.1 Stream流的创建 主要分为Collection(List与Set)、Map、数组三种创建方式: //1.Collection集合的创建List<String> names new ArrayList<>();Collections.addAll(…...

大语言模型 21 - MCP 自动操作 Figma+Cursor 实现将原型转换为代码
MCP 基本介绍 官方地址: https://modelcontextprotocol.io/introduction “MCP 是一种开放协议,旨在标准化应用程序向大型语言模型(LLM)提供上下文的方式。可以把 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 提供了一种…...

QNAP NEXTCLOUD 域名访问
我是用docker compose方式安装的,虽然不知道是不是这么个叫法,废话不多说。 背景:威联通container station安装了nextcloud和lucky,lucky进行的域名解析和反代 先在想安装的路径、数据存储路径、数据库路径等新建文件夹。再新建…...
Spring MVC深度解析:控制器与视图解析及RESTful API设计最佳实践
引言 在现代Java Web开发领域,Spring MVC框架凭借其优雅的设计和强大的功能,已成为构建企业级Web应用的首选框架。本文将深入探讨Spring MVC的核心机制——控制器与视图解析,并详细讲解如何设计符合RESTful风格的API。无论你是刚接触Spring …...

华为OD机试真题——信道分配(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

比亚迪“双剑”电池获中汽中心权威认证,堪称“移动安全堡垒”。
在新能源汽车发展中,电池安全是重中之重。比亚迪的刀片电池与闪充刀片电池提前通过电池新国标全项检测,获中汽中心权威认证,堪称“移动安全堡垒”。 传统电池极端条件下易热失控,而刀片电池独特长条形设计,似刀片般&am…...

【mysql】mysql的高级函数、高级用法
mysql是最常用的数据库之一,常见的函数用法大家应该都很熟悉,本文主要例举一些相对出现频率比较少的高级用法 (注:需注意mysql版本,大部分高级特性都是mysql8才有的) 多值索引与虚拟列 主要是解决字符串索引问题,光说…...
了解一下C#的SortedSet
基础概念 SortedSet 是 C# 中的一个集合类型,位于 System.Collections.Generic 命名空间下。它是一个自动排序的集合,用于存储不重复的元素,并且会根据元素的自然顺序(默认排序)或自定义比较器进行排序,内…...

【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器
----翻译自Mazin Alalusi等人的文章 摘要 高性价比的 1550 nm DWDM平面外腔 (PLANEX) 激光器是干涉测量、布里渊、LIDAR 和其他光传感应用的最佳选择。其线宽<3kHz、低相位/频率噪声和极低的RIN。 简介 高性能光纤分布式传感技术是在过去几年中开发…...

Pytorch里面多任务Loss是加起来还是分别backward? | Pytorch | 深度学习
当你在深度学习中进入“多任务学习(Multi-task Learning)”的领域,第一道关卡可能不是设计网络结构,也不是准备数据集,而是:多个Loss到底是加起来一起backward,还是分别backward? 这个问题看似简单,却涉及PyTorch计算图的构建逻辑、自动求导机制、内存管理、任务耦合…...
K8S Pod调度方法实例
以下是一篇面向企业用户、兼具通俗易懂和实战深度的 Kubernetes Pod 调度方法详解博文大纲与正文示例。全文采用“图文(代码块)并茂 问答穿插 类比”方式,模拟了真实终端操作及输出,便于读者快速上手。 一、引言 为什么要关注 P…...
【mindspore系列】- 算子源码分析
本文会介绍mindspore的算子源码结构、执行过程以及如何编写一个自定义的mindspore算子。 源码介绍 首先,我们先从https://gitee.com/mindspore/mindspore/ 官网中clone源代码下来。 clone好代码后,可以看到源码的文件夹结构如下(只列出比较重要的文件夹): docsmindspore…...
学习日记-day17-5.27
完成目标: 知识点: 1.日期相关类_Calendar日历类 常用方法:int get(int field) ->返回给定日历字段的值void set(int field, int value) :将给定的日历字段设置为指定的值void add(int field, int amount) :根据日历的规则,为给定的日历字段添加或…...

一种比较精简的协议
链接地址为:ctLink: 一个比较精简的支持C/C的嵌入式通信的中间协议。 本文采用的协议格式如下 *帧头 uint8_t 起始字节:0XAF\ *协议版本 uint8_t 使用的协议版本号:当前为0X01\ *负载长度 uint8_t 数据段内容长…...

网络常识:网线和光纤的区别
网络常识:网线和光纤的区别 一. 介绍二. 网线2.1 什么是网线?2.2 网线的主要类别2.3 网线的优势2.4 网线的劣势 三. 光纤3.1 什么是光纤?3.2 光纤的主要类别3.3 光纤的优势3.4 光纤的劣势 四. 网线 vs 光纤:谁更适合你?…...

OpenCV CUDA模块图像过滤------创建一个 Scharr 滤波器函数createScharrFilter()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数用于创建一个 Scharr 滤波器(基于 CUDA 加速),用于图像的一阶导数计算。它常用于边缘检测任务中&#…...

html css js网页制作成品——HTML+CSS+js醇香咖啡屋网页设计(5页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
[特殊字符] 构建高内聚低耦合的接口架构:从数据校验到后置通知的分层实践
在现代企业系统开发中,接口结构设计的质量直接影响系统的稳定性、扩展性与可维护性。随着业务复杂度上升,单一层次的接口实现往往难以应对功能膨胀、事务一致性、后置扩展等需求。因此,我们提出一种面向复杂业务场景的接口分层模型࿰…...

brep2seq 源码笔记2
数学公式是什么def forward(self, noise_1, noise_2, real_z_pNone): if(real_z_p): z_p_ self.downsample(real_z_p) input_2 z_p_ noise_2 z_f self.gen_z_f(input_2) output real_z_p z_f else: …...

UE5 蓝图,隐藏一个Actor,同时隐藏它的所有子物体
直接用actor.sethideningame是不行的 要先找到根组件,这样就有覆盖子物体的选项了...