源码地址:https://github.com/alibaba/Sentinel
新手指南:https://github.com/alibaba/Sentinel/wiki/新手指南#公网-demo
官方文档:https://sentinelguard.io/zh-cn/docs/introduction.html
注解支持文档:https://github.com/alibaba/Sentinel/wiki/注解支持
源代码地址:Spring Cloud Alibaba Sentinel - - >流控规则 (快速使用案例),主要看Sentinel8040这个moudle
文章目录
- Sentinel 介绍
- 🔗 Sentinel 与 Hystrix 的对比
- 🔗 使用简介
- Sentinel 快速使用
- 🔗 1. 添加依赖关系
- 🔗 2. 定义资源
- 🔗 3. 定义规则
- 🔗 4. 检查效果
Sentinel 介绍
Sentinel 是阿里巴巴开源的,面向分布式服务架构的高可用组件 / 流量控制组件 (分布式系统的流量防卫兵)。随着微服务的流行,服务与服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制 (限流)、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景
Sentinel 承接了 Alibaba 近十年的双十一大促流量的核心场景,例如秒杀 (即突增流量控制在系统容器可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用服务等。
- 完备的实时监控
Sentinel 提供实时的监控功能。你可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模的集群的汇总运行情况。
- 广泛的开源生态
Sentinel 提供开箱即用,与其它开源框架/库的整合模块,例如Spring Cloud、Dubble、gRPC的整合。你只需引入相关的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点
Sentinel 提供简单易用、完善的 SPI 扩展点。你可以通过实现扩展点,快速的定制逻辑。例如定制规则管理,适配数据源等。
阿里巴巴开源的 Sentinel 是基础版,而双十一使用的是它们的内部版本。但阿里云提供了企业级的 Sentinel 服务 - - > 应用高可用服务 AHAS,也就是付费版本。其实开源的基础版本对于中小型互联网公司而言已经足够用了,而对于大型互联网公司则需要在 Sentinel 的基础上进行扩展)
🔗 Sentinel 与 Hystrix 的对比
|
| |
---|---|---|
隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
熔断降级策略 | 基于响应时间或失败比率 | 基于失败比率 |
实施指标实现 | 滑动窗口 | 滑动窗口 (基于RxJava) |
规则配置 | 支持多种数据源 | 支持多种数据源 |
扩展性 | 多个扩展点 | 插件形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于QPS、支持基于调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动、匀速器模式 | 不支持 |
系统负载保护 | 支持 | 不支持 |
控制台 | 开箱即用、可配置规则、查看秒级监控、机器发现等 | 不完善 |
常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC等 | Servlet、Spring Cloud Netflix |
配置持久化 | 可以配过nacos配置中心进行持久化 | 通过Git文件来持久化 |
🔗 使用简介
Sentinel 可以简单的分为 Sentinel 核心库 (sentinel-core依赖) 和 Dashboard (Sentinel控制台)。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果 (因为通过Sentinel控制台,我们可以更方便的设置规则,不仅效率提高了,还能进行实时监控,而无需编写java代码来设置规则)。 - - > 当然学习中还是以代码方式为准。
这篇文章主要介绍 Sentinel 核心库的使用。如果希望有一个最快最直接的了解,可以参考 新手指南 来获取一个最直观的感受。
我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:
- 定义资源
- 定义规则
- 检验规则是否生效
先把可能需要保护的资源定义好(埋点),之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
对于主流的框架,我们提供适配,只需要按照适配中的说明配置,Sentinel 就会默认定义提供的服务,方法等为资源。
注意:Sentinel 需要 JDK 1.8 或更高版本。
需要注意的是,Sentinel 并不是一定要在 Spring Cloud Alibaba 上使用的,我们可以单纯的去使用 Sentinel 核心库。它可以在分布式架构中使用,而不是一定要在微服务架构中使用。
Sentinel 快速使用
下面是一个简单的演示 - - - > demo地址 (运行 sentinel8040 这个moudle),指导新用户只需 3 个步骤即可使用 Sentinel。它还演示如何使用仪表板监视此演示。
🔗 1. 添加依赖关系
如果您使用的是 Maven,只需在pom.xml
中添加以下依赖项。
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
Sentinel 的流控规则、降级规则等都是针对项目中的接口来进行设置的,需要依赖 web 接口,需要引入 web场景启动器 spring-boot-starter-web 依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
🔗 2. 定义资源
创建一个接口,在接口中定义资源,资源名称一般和接口地址一致。
@GetMapping("/hello")
public String hello(){
Entry entry = null;
try {
// sentinel 针对资源进行限制的,通常这个资源名称会跟接口的地址名称保持一致
entry = SphU.entry(RESOURCE_NAME);
// 被保护的业务逻辑
String str = "hello word";
log.info("- - -> " + str + " <- - -");
return str;
} catch (BlockException e) {
// 资源访问阻止,被限流 或 被降级
// 进行相应的处理操作
log.info("block");
return "被流控了";
} catch (Exception e) {
// 若需要配置降级规则,需要通过这种方式记录业务异常
Tracer.traceEntry(e, entry);
}finally {
if(entry != null){
entry.exit();
}
}
return null;
}
🔗 3. 定义规则
接下来,通过流控规则来指定允许该资源通过的请求次数,例如下面的代码定义了资源 HelloWorld 每秒最多只能通过 1 个请求。
@PostConstruct // Spring的初始化方法
private static void initFlowRules(){
// 流控规则
List<FlowRule> rules = new ArrayList<>();
// 流控
FlowRule rule = new FlowRule();
// 设置受保护的资源(即为哪个资源进行流量控制)
rule.setResource(RESOURCE_NAME);
// 设置流控规则 QPS
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置受保护的资源阈值
// Set limit QPS to 20,设置每秒的访问数为20,超过20的部分就会进行限流
//rule.setCount(20);
// Set limit QPS to 1,设置每秒的访问数为1,超过1的部分就会到catch(BlockException e)里去
rule.setCount(1);
rules.add(rule);
// 加载配置好的规则
FlowRuleManager.loadRules(rules);
}
完成上面 3 步,Sentinel 就能够正常工作了。更多的信息可以参考 使用文档。
完整代码
@RestController
@Slf4j
public class HelloController {
private static final String RESOURCE_NAME = "hello";
private static final String USER_RESOURCE_NAME = "user";
private static final String DEGRADE_RESOURCE_NAME = "degrade";
/**
* 进行Sentinel流控规则
*
* Sentinel 所有的规则都是针对于接口来的,准确点说是针对资源来设置的
*/
@GetMapping("/hello")
public String hello(){
Entry entry = null;
try {
// sentinel 针对资源进行限制的,通常这个资源名称会跟接口的地址名称保持一致
entry = SphU.entry(RESOURCE_NAME);
// 被保护的业务逻辑,如果是RPC调用远程服务的接口,那么这里被保护的就是RPC远程服务接口
String str = "hello word";
log.info("- - -> " + str + " <- - -");
// 如果没有被流控,则正常返回
return str;
} catch (BlockException e) {
// 资源访问阻止,被限流 或 被降级
// 进行相应的处理操作
log.info("block");
// 如果被流控了,则返回被流控了
return "被流控了";
} catch (Exception e) {
// 若需要配置降级规则,需要通过这种方式记录业务异常
Tracer.traceEntry(e, entry);
}finally {
if(entry != null){
entry.exit();
}
}
return null;
}
@PostConstruct // Spring的初始化方法
private static void initFlowRules(){
// 流控规则
List<FlowRule> rules = new ArrayList<>();
// 流控
FlowRule rule = new FlowRule();
// 设置受保护的资源(即为哪个资源进行流量控制)
rule.setResource(RESOURCE_NAME);
// 设置流控规则 QPS
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置受保护的资源阈值
// Set limit QPS to 20,设置每秒的访问数为20,超过20的部分就会进行限流
//rule.setCount(20);
// Set limit QPS to 1,设置每秒的访问数为1,超过1的部分就会到catch(BlockException e)里去
rule.setCount(1);
rules.add(rule);
// 加载配置好的规则
FlowRuleManager.loadRules(rules);
}
}