>[info]**官方文档**[https://github.com/alibaba/Sentinel/wiki/](https://github.com/alibaba/Sentinel/wiki/)、[https://sentinelguard.io/zh-cn/docs/introduction.html](https://sentinelguard.io/zh-cn/docs/introduction.html) [TOC] ## Sentinel 是什么? * [Sentinel](https://github.com/alibaba/Sentinel/)是阿里巴巴开源的分布式系统的流量防卫组件,随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: * **丰富的应用场景**:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。 * **完备的实时监控**:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。 * **广泛的开源生态**:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。 * **完善的 SPI 扩展点**:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。 ## 示范 ### 1 如何接入 #### 1.1 首先引入 Sentinel starter。 ~~~ maven <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> gradle compile group: 'com.alibaba.cloud', name: 'spring-cloud-starter-alibaba-sentinel' ~~~ >注意: 从 Sentinel 1.5.0 开始仅支持 JDK 1.7 或者以上版本。Sentinel 1.5.0 之前的版本最低支持 JDK 1.6。 #### 1.2 接入限流埋点 * HTTP 埋点 Sentinel starter 默认为所有的 HTTP 服务提供了限流埋点,如果只想对 HTTP 服务进行限流,那么只需要引入依赖,无需修改代码。 * 自定义埋点 如果需要对某个特定的方法进行限流或降级,可以通过`@SentinelResource`注解来完成限流的埋点,示例代码如下: ~~~ @SentinelResource("resource") public String hello() { return "Hello"; } ~~~ >当然也可以通过原始的`SphU.entry(xxx)`方法进行埋点,可以参见[Sentinel 文档](https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8#%E5%AE%9A%E4%B9%89%E8%B5%84%E6%BA%90) #### 1.3 配置限流规则 Sentinel 提供了两种配置限流规则的方式:代码配置 和 控制台配置。本示例使用的方式为通过控制台配置。 1.3.1 通过代码来实现限流规则的配置。一个简单的限流规则配置示例代码如下,更多限流规则配置详情请参考更多详细内容可以参考[流量控制](https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6)。 理解上面规则的定义之后,我们可以通过调用`FlowRuleManager.loadRules()`方法来用硬编码的方式定义流量控制规则,比如: ~~~java private void initFlowQpsRule() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule(resourceName); // set limit qps to 20 rule.setCount(20); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); rule.setLimitApp("default"); rules.add(rule); FlowRuleManager.loadRules(rules); } ~~~ #### 1.4 配置降级、限流规则 **Sentinel 能通过控制台动态配置规则,不过这样配置不会持久化不建议这样做,建议搭配nacos实现动态配置并且配置持久化** Sentinel 内部提供了[动态规则的扩展实现 ReadableDataSource](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95#datasource-%E6%89%A9%E5%B1%95)。 Sentinel starter 整合了目前存在的几类 ReadableDataSource。只需要在配置文件中进行相关配置,即可在 Spring 容器中自动注册 DataSource。 比如要定义两个ReadableDataSource,分别是`FileRefreshableDataSource`和`NacosDataSource`,配置如下: ~~~ spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json spring.cloud.sentinel.datasource.ds1.file.data-type=json spring.cloud.sentinel.datasource.ds1.file.rule-type=degrade spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP spring.cloud.sentinel.datasource.ds2.nacos.data-type=json ~~~ `ds1`和`ds2`表示ReadableDataSource的名称,可随意编写。`ds1`和`ds2`后面的`file`和`nacos`表示ReadableDataSource的类型。 目前支持`file`,`nacos`,`zk`,`apollo`这4种类型。 其中`nacos`,`zk`,`apollo`这3种类型的使用需要加上对应的依赖`sentinel-datasource-nacos`,`sentinel-datasource-zookeeper`,`sentinel-datasource-apollo`。 当ReadableDataSource加载规则数据成功的时候,控制台会打印出相应的日志信息: ~~~ [Sentinel Starter] DataSource ds1-sentinel-file-datasource load 3 DegradeRule [Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule ~~~ #### 1.5 自定义限流处理逻辑 * 默认限流异常处理 URL 限流触发后默认处理逻辑是,直接返回 "Blocked by Sentinel (flow limiting)"。 如果需要自定义处理逻辑,实现的方式如下: ~~~ public class CustomUrlBlockHandler implements UrlBlockHandler { @Override public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException { // todo add your logic } } WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler()); ~~~ * 使用`@SentinelResource`注解下的限流异常处理 如果需要自定义处理逻辑,填写`@SentinelResource`注解的`blockHandler`属性(针对所有类型的`BlockException`,需自行判断)或`fallback`属性(针对熔断降级异常),注意**对应方法的签名和位置有限制**,详情见[Sentinel 注解支持文档](https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81#sentinelresource-%E6%B3%A8%E8%A7%A3)。示例实现如下: ~~~ public class TestService { // blockHandler 是位于 ExceptionUtil 类下的 handleException 静态方法,需符合对应的类型限制. @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class}) public void test() { System.out.println("Test"); } // blockHandler 是位于当前类下的 exceptionHandler 方法,需符合对应的类型限制. @SentinelResource(value = "hello", blockHandler = "exceptionHandler") public String hello(long s) { return String.format("Hello at %d", s); } public String exceptionHandler(long s, BlockException ex) { // Do some log here. ex.printStackTrace(); return "Oops, error occurred at " + s; } } ~~~ ~~~ public final class ExceptionUtil { public static void handleException(BlockException ex) { System.out.println("Oops: " + ex.getClass().getCanonicalName()); } } ~~~ ### 2 启动 Sentinel 控制台 首先需要获取 Sentinel 控制台,支持直接下载和源码构建两种方式。 2.1 直接下载:[下载 Sentinel 控制台](https://github.com/alibaba/Sentinel/releases)(下载截止目前为止最新版本的控制台 jar 包) 2.2 源码构建:进入 Sentinel[Github 项目页面](https://github.com/alibaba/Sentinel),将代码 git clone 到本地自行编译打包,[参考此文档](https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard)。 2.3 启动控制台,执行 Java 命令`java -jar -Dserver.port=6999 sentinel-dashboard.jar`完成 Sentinel 控制台的启动。 > **控制台默认的监听端口为 8080,本项目修改为6999。**