Sentinel,阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。分布式系统的流量防卫兵。
特征:
Sentinel分为两个部分:
Sentinel提供一个轻量级的控制台,具备机器发现、单机资源实时监控、集群资源汇总及规则管理等功能。从GitHub Release下载最新版,启动命令:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
浏览器访问http://localhost:8080/
,默认用户名密码:sentinel/sentinel。进入后会发现只有一个服务实例,也就是sentinel-dashboard
本身
引入依赖:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
需要想要应用出现在Sentinel Dashboard监控列表里面,可以在应用配置文件里增加如下配置:
spring:
cloud:
sentinel:
transport:
port: 9999 # 跟控制台交流的端口,随意指定一个未使用的端口即可
dashboard: localhost:8080 # 指定控制台服务的地址
问题:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
<version>0.2.1.RELEASEversion>
dependency>
后升级到
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
<version>2.1.4.RELEASEversion>
dependency>
手动移除,刷新页面:
另外有一个服务分子是0,不难分析出此服务已下线:
问题:
参考Sentinel/wiki/控制台#控制台配置项
但是,并没有解决问题。
概念:
容错功能,主要体现为下面这三个:
Sentinel支持5种规则:
监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
阈值类型/单机阈值:
sentinel共有三种流控模式:
流控效果
也叫熔断规则,Sentinel提供三个衡量条件:
[0.0, 1.0]
热点参数流控规则是一种更细粒度的流控规则,它允许将规则具体到参数上。参数例外项允许对一个参数的具体值进行流控
需要根据调用来源来判断该次请求是否允许放行,这时候可以使用Sentinel的来源访问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过:
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体Load、RT、入口QPS、CPU使用率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量(进入应用的流量)生效。
maxQps * minRt
计算得出。设定参考值一般是CPU cores * 2.5
。Sentinel的理念是开发者只需要关注资源的定义,当资源定义成功,可以动态增加各种流控、降级规则。
Sentinel提供两种方式修改规则:
可以通过Dashboard来为每个Sentinel客户端设置各种各样的规则,这些规则默认是存放在内存中,所以需要将其持久化。
通过API修改规则比较直观:
FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则
SystemRuleManager.loadRules(List<SystemRule> rules); // 修改系统规则
上述loadRules()
方法只接受内存态的规则对象,但应用重启后内存中的规则就会丢失,更多的时候规则最好能够存储在文件、数据库或者配置中心中。
DataSource接口提供对接任意配置源的能力。相比直接通过API修改规则,实现DataSource接口是更加可靠的做法。
官方推荐通过控制台设置规则后将规则推送到统一的规则中心,用户只需要实现DataSource接口,来监听规则中心的规则变化,以实时获取变更的规则。
DataSource拓展常见的实现方式:
可用于指定出现异常时的处理策略。主要参数如下:
属性 | 作用 |
---|---|
value | 资源名称 |
entryType | entry类型,标记流量的方向,取值IN/OUT,默认OUT |
blockHandler | 处理BlockException的函数名称,函数要求: 1. 必须是public 2. 返回类型 参数与原方法一致 3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置blockHandlerClass,并指定blockHandlerClass里面的方法 |
blockHandlerClass | 存放blockHandler的类,对应的处理函数必须static修饰 |
fallback | 用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除exceptionsToIgnore里面排除掉的异常类型)进行处理。函数要求: 1. 返回类型与原方法一致 2. 参数类型需要和原方法相匹配 3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置fallbackClass,并指定fallbackClass里面的方法。 |
fallbackClass | 存放fallback的类。对应的处理函数必须static修饰 |
defaultFallback | 通用的fallback逻辑。默认fallback函数可以针对所有类型的异常进行处理。若同时配置fallback和defaultFallback,以fallback为准。函数要求: 1. 返回类型与原方法一致 2. 方法参数列表为空,或有一个Throwable类型的参数。 3. 默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置fallbackClass,并指定fallbackClass里面的方法。 |
exceptionsToIgnore | 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。 |
exceptionsToTrace | 需要trace的异常 |
节点 | 作用 |
---|---|
StatisticNode | 执行具体的资源统计操作 |
DefaultNode | 该节点持有指定上下文中指定资源的统计信息,当在同一个上下文中多次调用entry方法时,该节点可能下会创建有一系列的子节点。另外每个DefaultNode中会关联一个ClusterNode |
ClusterNode | 该节点中保存资源的总体的运行时统计信息,包括rt,线程数,qps等等,相同的资源会全局共享同一个ClusterNode,不管他属于哪个上下文 |
EntranceNode | 该节点表示一棵调用链树的入口节点,通过他可以获取调用链树中所有的子节点 |
每种Slot的功能职责:
每个Slot执行完业务逻辑处理后,会调用fireEntry()
方法,该方法将会触发下一个节点的entry方法,下一个节点又会调用其fireEntry()
,以此类推直到最后一个Slot,由此就形成Sentinel的责任链。
框架 | Sentinel | Hystrix | resilience4j |
---|---|---|---|
隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 | 基于异常比率、响应时间 |
实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于RxJava) | Ring Bit Buffer |
动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
流量整形 | 支持预热模式、匀速器模式、预热排队模式 | 不支持 | 简单的Rate Limiter模式 |
系统自适应保护 | 支持 | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 |
原则是一致的:当一个资源出现问题时,让其快速失败,不要波及到其它服务。
但是在限制的手段上,采取完全不一样的方法: