Sentinel介绍
Sentinel是一个面向云原生微服务的流量控制、熔断降级组件。替代Hystrix,针对问题:服务雪崩、服务降级、服务熔断、服务限流。
Sentinel 分为两个部分:
- 核心库:(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
- 控制台:(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等
Sentinel 的主要特性:
Sentinel部署
下载地址:https://github.com/alibaba/Sentinel/releases 。我们使用v1.7.1。
启动:java -jar sentinel-dashboard-1.7.1.jar &
用户名/密码:sentinel/sentinel
服务集成
我们的服务集成Sentinel也很简单,只需要引入如下依赖:
<!--sentinel 核心环境依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<!--SCA -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SCA -->
</dependencies>
</dependencyManagement>
添加上Sentinel的配置项:
spring:
cloud:
sentinel:
transport:
# sentinel dashboard/console地址
dashboard: 127.0.0.1:8080
# sentinel会在该端口启动http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来
# 如果8719端口被占⽤,那么会依次+1
port: 8719
至此,我们的Sentinel就集成好了。我们可以发一个请求到该服务器,然后查看Sentinel Dashboard( 注意:Sentinel Dashboard 是懒加载的,不发起调用是没有数据的)。
Sentinel关键概念
概念名称 | 概念描述 |
资源 | 它可以是Java应用程序中的任何内容。例如:由应用程序提供的服务、由应用程序调用的其他应用提供的服务甚至可以是一段代码。我们请求对的API接口就是资源 |
规则 | 围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整 |
Sentinel限流模块
我们系统的并发能力有限,如果太多请求过来,我们就应该进行流量控制。使用Sentinel设定限流规则的示例如下:
- 资源名:默认是请求路径
- 针对来源:Sentinel可以针对调用者进行限流,填写微服务名称,默认default(不区分来源)
- 阈值类型和单机阈值:QPS(每秒钟请求数量)是指调用该资源的QPS达到阈值时进行限流;线程数是指当调用该资源的线程数达到阈值时进行限流(线程处理请求的时候,如果说业务逻辑执行时间很长,流量洪峰来临时,会耗费很多线程资源,这些线程资源会堆积起来造成服务的不可用,进一步就有可能影响的上游不可用而引发服务雪崩)
- 是否集群:是否是集群限流
- 流控模式:直接是指资源调用达到限流条件时,直接限流;关联是指关联的资源达到限流条件了就限流自己;链路是指只记录指定链路上的流量
- 流控效果:快速失败是指直接失败,抛出异常;Warm Up是指根据冷加载因子(默认是3)的值,从阈值/冷加载因子,经过预热时长,才达到设置的QPS阈值;排队等待是指匀速排队,让请求匀速通过,阈值类型必须设置为QPS,否则无效
流控模式之关联限流
关联的资源调用达到阈值的时候限流自己。比如用户注册接口,需要调用身份证校验接口。如果身份证校验接口请求达到阈值,使用关联,就可以对用户注册接口也进行限流。
流控模式之链路限流
链路指的是请求链路(调用链)。链路模式下会控制资源所在的调用链路入口的流量。需要在规则中配置入口资源,即该调用链路入口的上下文名称。
上图中来自入口Entrance1
和Entrance2
的请求都调用到了资源NodeA
,Sentinel允许只根据某个调用入口的统计信息对资源限流。比如链路模式下设置入口资源为Entrance1,则只有该入口的调用才会记录到NodeA
的限流统计中,而不关心Entrance2的调用。
流控效果之Warm Up
当系统长期处于空闲的情况下,流量的突然增加会直接把系统拉升到高水位,从而可能瞬间压垮系统。比如电商网站的秒杀模块等等。
通过Warm Up模式可以让通过的流量缓慢增加,经过预热时间以后达到系统处理速率的设定值。这样,就避免了上述问题与风险,增加了系统的稳定性。
流控效果之排队等待
排队等待模式下会严格控制请求通过的间隔时间,即请求会匀速通过,允许部分请求排队等待,通常用于消息队列削峰填谷等场景。需设置具体的超时时间,当计算的等待时间超过超时时间时请求就会被拒绝。
很多流量过来了,并不是直接拒绝请求,而是请求进行排队,⼀个⼀个匀速通过(处理),请求能等就等着被处理,不能等(等待时间>超时时间)就会被拒绝。例如,QPS 配置为 5,则代表请求每 200 ms 才能通过⼀个,多出的请求将排队等待通过。超时时间代表最大排队时间,超出最大排队时间的请求将会直接被拒绝。排队等待模式下,QPS 设置值不要超过 1000(请求间隔 1 ms)。
Sentinel熔断降级
流控是对外部来的大流量进行控制,熔断降级的视⻆是对内部问题进行处理。Sentinel降级会在调用链路中某个资源出现不稳定状态时(调用超时或异常),就对着个资源的调用进行限制,让请求快速失败来避免影响到其他的资源。当资源被降级之后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(这里跟Hystrix不同,Sentinel没有自动修复功能,只能等到时间窗口内过完)。
降级策略之RT(平均响应时间)
当1秒内持续进入5个及以上的请求,平均响应时间超过了设定的阈值(以毫秒为单位),那么在接下来的时间窗口内(以秒为单位),对这个方法的调用就会直接抛出异常(DegradeException)。需要注意的是:Sentinel默认统计的RT上限是4900ms,超出此阈值都会算作4900ms。若需要更改此上限可以通过配置启动配置项-Dcsp.sentinel.statistic.max.rt=xxx
来配置。
降级策略之异常比例
当1秒内持续进入5个及以上的请求,并且每秒异常总数占通过量的比例超过阈值之后,资源进入降级状态。即在接下来的时间窗口内(以s为单位),岁这个方法的调用都会自动返回。 异常比率的阈值范围是 [0.0, 1.0] ,代表 0% - 100%。
降级策略之异常数
当资源近1分钟的异常数超过阈值之后会进行自动熔断。注意由于统计时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态之后仍可能再次进入熔断状态。
Sentinel自定义兜底逻辑
@SentinelResource
注解类似于Hystrix中的@HystrixCommand
注解。@SentinelResource
注解中有两个属性需要我们进行区分,blockHandler
属性用来指定不满足Sentinel规则的降级兜底方法,fallback
属性用于指定Java运行时异常兜底方法。
@SentinelResource(value = "sentinel",
blockHandlerClass = SentinelFallbackClass.class,
blockHandler = "handleBlock",
fallbackClass = SentinelFallbackClass.class,
fallback = "handleException"
)
public String sentinel() {
if (random.nextBoolean()) {
int i = 3/0;
}
return irResumeService.hello();
}
package com.rubin.autodeliver.fallback;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class SentinelFallbackClass {
public static String handleBlock(BlockException blockException) {
blockException.printStackTrace();
return "被Sentinel限流了";
}
public static String handleException() {
return "调用失败了,直接熔断";
}
}
在这里需要注意,我们的兜底方法可以定义在本类,也可以定义在其他类。定义在本类或者其他类其参数和返回值均要跟原方法一致,但定义在外部类方法要定义为静态的。
基于Nacos实现Sentinel规则持久化
目前,Sentinel Dashboard中添加的规则数据存储在内存,微服务停掉规则数据就消失,在生产环境下不合适。我们可以将Sentinel规则数据持久化到Nacos配置中心,让微服务从Nacos获取规则数据。
我们需要在Sentinel微服务中添加如下依赖:
<!-- Sentinel⽀持采用 Nacos 作为规则配置数据源,引入该适配依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
将Sentinel配置修改如下:
spring:
cloud:
sentinel:
transport:
# sentinel dashboard/console地址
dashboard: 127.0.0.1:8080
# sentinel会在该端口启动http server,那么这样的话,控制台定义的⼀些限流等规则才能发送传递过来
# 如果8719端口被占⽤,那么会依次+1
port: 8719
# Sentinel Nacos数据源配置,Nacos中的规则会⾃动同步到sentinel控制台的流控规则中
datasource:
# 此处的flow为⾃定义数据源名
# 流控规则
flow:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
data-id: ${spring.application.name}-flow-rules.json
groupId: DEFAULT_GROUP
data-type: json
# 类型来⾃RuleType类
rule-type: flow
degrade:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: 651d1e6f-4bf4-46b9-b5b0-1885a215dc12
data-id: ${spring.application.name}-degrade-rules.json
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade
其中的namespace是我们自定义添加的命名空间,不填默认是public
命名空间。我们在自定义的命名空间下添加如下配置项:
${spring.application.name} -flow-rules.json:
[
{
"resource":"sentinel",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]
其所有属性来自源码FlowRule
类:
- resource:资源名称
- limitApp:来源应用
- grade:阈值类型 0 线程数 1 QPS
- count:单机阈值
- strategy:流控模式,0 直接 1 关联 2 链路
- controlBehavior:流控效果,0 快速失败 1 Warm Up 2 排队等待
- clusterMode:true/false 是否集群
${spring.application.name}-degrade-rules.json :
[
{
"resource":"sentinel",
"grade":2,
"count":1,
"timeWindow":5
}
]
其所有属性来自源码DegradeRule
类:
- resource:资源名称
- grade:降级策略 0 RT 1 异常比例 2 异常数
- count:阈值
- timeWindow:时间窗
Rule
源码体系结构:
注意:
- ⼀个资源可以同时有多个限流规则和降级规则,所以配置集中是⼀个json数组
- Sentinel控制台中修改规则,仅是内存中生效,不会修改Nacos中的配置值,重启后恢复原来的值; Nacos控制台中修改规则,不仅内存中生效,Nacos中持久化规则也生效,重启后规则依然保持
以上就是关于Sentinel的全部内容。欢迎小伙伴们积极留言交流~~~
文章评论