Sentinel: 分布式系统的流量防卫兵
Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
官网:https://github.com/alibaba/Sentinel
中文官网:https://github.com/alibaba/Sentinel/wiki
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性:
Sentinel 的开源生态:
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
Sentinel 重要概念
定义资源
资源 是 Sentinel 中的核心概念之一。最常用的资源是我们代码中的 Java 方法。 当然,您也可以更灵活的定义你的资源,例如,把需要控制流量的代码用 Sentinel API SphU.entry("HelloWorld")
和 entry.exit()
包围起来即可。在下面的例子中,我们将 System.out.println("hello world");
作为资源(被保护的逻辑),用 API 包装起来。参考代码如下:
1 public static void main(String[] args) { 2 // 配置规则. 3 initFlowRules(); 4 5 while (true) { 6 // 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry 7 try (Entry entry = SphU.entry("HelloWorld")) { 8 // 被保护的逻辑 9 System.out.println("hello world"); 10 } catch (BlockException ex) { 11 // 处理被流控的逻辑 12 System.out.println("blocked!"); 13 } 14 } 15 }
也可以通过我们提供的 注解支持模块,来定义我们的资源,类似于下面的代码:
1 @SentinelResource("HelloWorld") 2 public void helloWorld() { 3 // 资源中的逻辑 4 System.out.println("hello world"); 5 }
这样,helloWorld()
方法就成了我们的一个资源。注意注解支持模块需要配合 Spring AOP 或者 AspectJ 一起使用。
定义规则
接下来,通过流控规则来指定允许该资源通过的请求次数,例如下面的代码定义了资源 HelloWorld
每秒最多只能通过 20 个请求。
1 private static void initFlowRules(){ 2 List<FlowRule> rules = new ArrayList<>(); 3 FlowRule rule = new FlowRule(); 4 rule.setResource("HelloWorld"); 5 rule.setGrade(RuleConstant.FLOW_GRADE_QPS); 6 // Set limit QPS to 20. 7 rule.setCount(20); 8 rules.add(rule); 9 FlowRuleManager.loadRules(rules); 10 }
完成上面 ,Sentinel 就能够正常工作了。更多的信息可以参考官网。
Sentinel使用
案例架构图如下:
搭建Sentinel控制台
1、下载sentienl的jar包,本例使用:sentinel-dashboard-1.7.2.jar,地址:https://github.com/alibaba/Sentinel/releases
2、使用java -jar命令启动Sentinel控制台,注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
命令格式:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
如若8080端口冲突,可使用 -Dserver.port=新端口
进行设置。
命令:java -jar sentinel-dashboard-1.7.2.jar
3、访问地址:http://localhost:8080/,8080为Sentinel的默认端口
4、输入默认用户名/密码:sentinel/sentinel,进入首页
搭建Sentinel客户端
1、新建项目Spring Cloud项目(springcloud-sentinel-service8401)
2、编辑pom.xml文件,引入依赖
1 <!-- alibaba nacos sentinel --> 2 <dependency> 3 <groupId>com.alibaba.cloud</groupId> 4 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> 5 </dependency>
完整pom,如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>test-springcloud</artifactId> 7 <groupId>com.test</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>springcloud-sentinel-service8401</artifactId> 13 14 <dependencies> 15 16 <!-- alibaba nacos sentinel --> 17 <dependency> 18 <groupId>com.alibaba.cloud</groupId> 19 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> 20 </dependency> 21 22 <!-- alibaba nacos discovery --> 23 <dependency> 24 <groupId>com.alibaba.cloud</groupId> 25 <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> 26 </dependency> 27 28 <!-- spring boot --> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-web</artifactId> 32 </dependency> 33 <dependency> 34 <groupId>org.springframework.boot</groupId> 35 <artifactId>spring-boot-starter-actuator</artifactId> 36 </dependency> 37 <dependency> 38 <groupId>org.springframework.boot</groupId> 39 <artifactId>spring-boot-devtools</artifactId> 40 <scope>runtime</scope> 41 <optional>true</optional> 42 </dependency> 43 <dependency> 44 <groupId>org.projectlombok</groupId> 45 <artifactId>lombok</artifactId> 46 <optional>true</optional> 47 </dependency> 48 <dependency> 49 <groupId>org.springframework.boot</groupId> 50 <artifactId>spring-boot-starter-test</artifactId> 51 <scope>test</scope> 52 </dependency> 53 54 </dependencies> 55 </project>
3、编辑application.yml文件
1 # 端口 2 server: 3 port: 8401 4 5 spring: 6 application: 7 name: alibaba-sentinel-service 8 cloud: 9 nacos: 10 discovery: 11 server-addr: localhost:8848 12 sentinel: 13 transport: 14 # 配置Sentinel DashBoard地址 15 dashboard: localhost:8080 16 # 应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer 17 # 默认8719端口,假如端口被占用,依次+1,直到找到未被占用端口 18 port: 8719 19 20 management: 21 endpoints: 22 web: 23 exposure: 24 include: '*'
4、编辑主启动类
1 @SpringBootApplication 2 @EnableDiscoveryClient 3 public class SentinelMain8401 { 4 public static void main(String[] args) { 5 SpringApplication.run(SentinelMain8401.class, args); 6 } 7 }
5、编辑一个Controller
1 @RestController 2 public class FlowLimitController { 3 4 @GetMapping("/testA") 5 public String testA(){ 6 return "--------testA"; 7 } 8 9 @GetMapping("/testB") 10 public String testB(){ 11 return "--------testB"; 12 } 13 }
6、测试
1)启动项目,启动Nacos服务(【SpringCloud】Spring Cloud Alibaba 之 Nacos注册中心(二十七))
启动Sentinel控制台
2)在浏览器中访问地址:http://localhost:8401/testA
3)查看Sentinel控制台-〉选择alibaba-sentinel-service服务-〉实时监控-〉可以看到监控详情
4)同时可以查看簇点链路
5)同时可以查看机器列表