Sentinel原理之规则管理
文章目录
- 1. 基础知识
- 2. 数据源使用
- 2.1 RedisDatasource
- 2.2 ZookeeperDatasource
1. 基础知识
流量控制规则(FlowRule):
- 阈值类型grade:
- 0(并发线程数):限制同时处理请求的线程
- 1(QPS):限制每秒请求数
- 阈值count:单机阈值,如QPS=100,并发线程数=10
- 流控模式strategy:
- 0(直接模式):达到阈值即限流,默认
- 1(关联模式):关联资源超阈值时限流本资源,如支付接口超限,限制下单接口
- 2(链路模式):仅统计指定入口的流量
- 流控效果controlBehavior:
- 0(快速失败):超阈值直接拒绝,默认
- 1(预热启动):在规定的时间内从下限逐步提升到上限(如3s从3QPS升至10QPS),冷启动因子默认为3,即阈值是100QPS,初始QPS为30
- 2(匀速排队):请求按固定间隔通过(漏桶算法),需要设置超时时间
- 3(预热匀速排队):预热阶段多出的请求匀速排队,进入正常阶段继续使用匀速排队处理请求
- 规则管理类:以resource资源名称为key,流量控制规则为value管理在FlowRuleManager
- 实际流量控制逻辑:加载规则时会根据controlBehavior属性创建对应的流量控制器,指标从节点中获取,在流量控制器中进行规则判断
- 默认流控DefaultController:处理线程流控及QPS快速失败流控
- 预热启动WarmUpController:处理QPS的预热启动流控
- 匀速排队RateLimiterController:处理QPS的匀速排队流控
- 预热匀速排WarmUpRateLimiterController:处理QPS的预热匀速排队流控
熔断降级规则(DegradeRule):
- 熔断策略grade:
- 0(慢调用比例):在统计窗口内调用时间大于判定时间,且在窗口内比例大于慢调用阈值则熔断
- 1(异常比例):在统计窗口内抛异常的数量占比大于总请求数则熔断
- 2(异常数):在统计窗口内抛异常的数大于阈值则熔断
- 熔断阈值count:分别对应慢调用时间阈值、异常比例阈值、异常数量阈值
- 熔断时间timeWindow:熔断持续时间(秒),超时后进入半开状态试探
- 最小请求数minRequestAmount:在统计窗口内触发熔断的最小请求数
- 统计窗口statIntervalMs:统计窗口时间,单位毫秒
- 慢调用比例阈值slowRatioThreshold:仅慢调用模式生效,0.0~1.0
- 规则管理类:以resource资源名称为key,熔断降级规则为value管理在DegradeRuleManager
- 实际熔断降级逻辑:加载规则时会根据grade属性创建对应的断路器(CircuitBreaker),在断路器中记录指标和判断规则
- 响应时间断路器ResponseTimeCircuitBreaker:grade=0,记录超时请求数和总请求数进行判断
- 异常断路器ExceptionCircuitBreaker:grade=1或2,记录失败次数和总请次数进行判断
Sentinel规则可以从Nacos、Apollo、Zookeeper、Consul、Redis或读取文件获取,基本涵盖了国内常的几个持久化数据框架
sentinel的数据源配置时可自定义key名称,value为对应的数据源配置,如下:
spring:cloud:sentinel:customDb1:zk:server-addr: localhost:xxxxpath: xxxxxxxx/xxxxrule-type: flowfixDb2:redis:host: localhostport: 6379password: xxxxxxrule-type: degrade
配置单个数据源只能获取一种类型的规则,如要获取flow和degrade规则,则数据源需要配置两次,分别指定ruleType类型获取
数据源常用的ruleType有:
- flow:流量控制,对应FlowRule
- degrade:熔断限流,对应DegradeRule
- param-flow:热点参数流量控制,对应ParamFlowRule
- system:系统指标控制,对应SystemRule
当从数据源拉取数据后,需要将数据源的数据格式转化为对应的规则格式,官方默认的格式要求是json,额外支持xml格式,由数据源的dataType属性控制
若需要自定义数据格式,并转换为对应的规则类型,有两种方式:
- 仅指定dataType:
- 前置条件:如转换properties文件
- dataType=properties
- 实现sentinel的Converter接口
- 实现类需要注册beanName到spring容器中
- 名称规则:beanName=
sentinel-{dataType}-{ruleType}-converter
- 名称示例:
sentinel-properties-flow-converter
代表支持使用dataType=properties的Converter实现类 - 官方支持的dataType:
- json:sentinel-json-flow-converter、sentinel-json-degrade-converter等
- xml:sentinel-xml-flow-converter、sentinel-xml-degrade-converter等
- 前置条件:如转换properties文件
- 自定义dataType:
- 前置条件
- dataType=custom
- 配置converterClass
- 实现sentinel的Converter接口
- 实现类需要注册beanName到spring容器中
- 名称规则:beanName=
sentinel-{converterClass}
- 实现效果:从指定数据源拉取到数据后使用converterClass对应实现类转换数据为规则列表
- 前置条件
2. 数据源使用
Nacos、Apollo和Consul要求程序必须使用这三个分布式数据框架,适用性较低。Redis和Zookeeper大部分中间件都会依赖,因此这两种方式更具有普遍实用价值
2.1 RedisDatasource
使用redis需要配置下面几个关键属性:
- host:地址
- port:端口
- password:连接密码
- ruleKey:初始化时拉取规则的key
- channel:使用Pub/Sub机制订阅的channel,要求发布者往该channel发布消息
配置完redis数据源后会注册RedisDataSourceFactoryBean到spring容器中,在工厂bean中初始化RedisDataSource
初始化数据源时使用ruleKey从redis拉取对应的键值,再使用对应的converter转化数据格式给对应的规则管理类加载使用
后续规则更新时,不仅要求规则更新系统修改ruleKey对应的键值,还需要系统使用redis的Pub/Sub机制往channel发送最新规则值,这样依赖系统才会使用最新规则数据
Pub/Sub机制拥有诸多缺陷,因此在Sentinel没有把通知机制修改为Stream前,不太推荐使用RedisDatasource来作为中间件存储规则
2.2 ZookeeperDatasource
使用zookeeper只需要配置两个关键属性:
- serverAddr:完整的连接地址端口
- path:对应的获取/监听数据节点路径
配置path相当于直接指定了完整的zk节点,除了这种外还有另一种配置方式:使用groupId和dataId代替path。其等效于path=/{groupId}/{dataId}
,若配置了groupId和dataId,则优先使用该方式
配置完zk数据源后会注册ZookeeperDataSourceFactoryBean到spring容器中,在工厂中初始化ZookeeperDataSource
初始化数据源时会使用Curator连接zk,使用NodeCache监听对应路径的数据节点,当数据节点发生变化时则触发更新
连接zk成功后将会使用NodeCache获取监听节点数据
当获得数据节点数据后,会使用converter转换为对应规则,最后再把规则给对应规则管理器加载使用
若项目没有使用Nacos、Apollo,相对Redis,更推荐使用zk来作为中间件发布规则数据