Sentinel 流量控制
一、sentinel是什么
流控降级 Sentinel 是面向分布式服务架构的专业流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统保护等多个维度来帮助您保障服务的稳定性,同时提供强大的聚合监控和历史监控查询功能
流控降级 Sentinel,由阿里巴巴集团自主研发, 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等,是阿里巴巴双十一使用的核心产品。
(引用自sentinel官方文档)
二、sentinel 原理解析
1.架构概述:
Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建;每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain)。这些插槽有不同的职责,例如:
NodeSelectorSlot
负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;ClusterBuilderSlot
则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;StatisticSlot
则用于记录、统计不同纬度的 runtime 指标监控信息;FlowSlot
则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;AuthoritySlot
则根据配置的黑白名单和调用来源信息,来做黑白名单控制;DegradeSlot
则通过统计信息以及预设的规则,来做熔断降级;SystemSlot
则通过系统的状态,例如 load1 等,来控制总的入口流量;
总体的框架如下:
Sentinel 将 SlotChainBuilder
作为 SPI 接口进行扩展,使得 Slot Chain 具备了扩展的能力。您可以自行加入自定义的 slot 并编排 slot 间的顺序,从而可以给 Sentinel 添加自定义的功能。
(引用自sentinel官方文档)
2.资源处理
使用责任链模式处理资源
3.规则
Sentinel有提供3种规则或者说是策略来对资源进行管控,存在管控台可以动态实时调整:
1.系统保护规则SystemRule
- Load (仅对 Linux/Unix-like 机器生效):当系统 Load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
2.流量控制规则FlowRule
- resource:资源名,即限流规则的作用对象
- count: 限流阈值
- grade: 限流阈值类型(QPS 或并发线程数)
- limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
- strategy: 调用关系限流策略
- controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)
3.熔断降级规则DegradeRule
- resource:资源名
- count: 限流阈值
- grade: 限流阈值类型(QPS 或并发线程数)
- timeWindow: 降级的时间窗口
4.规则加载
- 所有的规则都可以通过对应的硬编码模式XxxRuleManager来加载
- 可以在内存中通过动态的修改生效,通过API来进行修改。
- Sentinel有提供通过实现DataSource接口的方式来定义规则的存储
三、sentinel 如何集成(采用AOP方式接入)
1.集成到apollo(动态推送)
sentienl-apollo demo :https://github.com/laimailai2018/springboot_learn/tree/master/sentinel_apollo
1.sentinel控制台修改规则,推送到apollo服务端
2.apollo服务端推送到客户端,使配置生效
如果要做到图示sentinel dashboard(控制台) 修改后推送到apollo,需要对控制台源码进行修改。
1.1 maven依赖:
com.alibaba.csp sentinel-core 1.4.1 com.alibaba.csp sentinel-annotation-aspectj 1.4.1 com.alibaba.csp sentinel-transport-simple-http 1.4.1 com.alibaba.csp sentinel-datasource-apollo 1.4.1
1.2 aop切入
//配置AOP切入 @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }
1.3 加载apollo动态规则
@Bean public void loadRules() { //apollo appid String appId = "apollo-appid"; //apollo 服务地址 String apolloMetaServerAddress = "http://localhost:XXXX"; System.setProperty("app.id", appId); System.setProperty("apollo.meta", apolloMetaServerAddress); //apollo应用空间 String namespaceName = "application"; //apollo 限流规则key String flowRuleKey = "sentinel.flowrule.key"; //sentinel 默认规则,连接apollo失败时调用的规则,这里设置为空 String defaultFlowRules = "[]"; ReadableDataSource> flowRuleDataSource = new ApolloDataSource<>(namespaceName, flowRuleKey, defaultFlowRules, source -> JSON.parseObject(source, new TypeReference >() { })); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); }
1.4 注解方式接入
@SentinelResource(value = "test") public void test() throws Exception { System.out.println("test!"); }
1.5 jvm参数配置
#sentinel控制台 ,需要另外启动一个项目,可选 -Dcsp.sentinel.dashboard.server=localhost:8080 #本服务在sentinel控制台的名称,可选 -Dproject.name=laimailai #调用apollo的环境 -Denv=DEV #apollo服务地址 -Dapollo.configService=http://localhost:XXXX
1.6 apollo限流规则编写
key: sentinel.flowrule.key value: [ { "resource": "test", "controlBehavior": 0, "count": 1, "grade": 1, "limitApp": "default", "strategy": 0 } ]
访问localhost:XXXX/test 进行测试
2.集成AHAS(推荐)
2.1 maven依赖:
sentinel 1.4.0版本必须搭配ahas-sentinel-client 1.0.4版本使用(别问我怎么知道的 o(╥﹏╥)o)
sentinel 1.4.0版本必须搭配ahas-sentinel-client 1.0.4版本使用(别问我怎么知道的 o(╥﹏╥)o)
sentinel 1.4.0版本必须搭配ahas-sentinel-client 1.0.4版本使用(别问我怎么知道的 o(╥﹏╥)o)
com.alibaba.csp sentinel-core 1.4.0 com.alibaba.csp sentinel-annotation-aspectj 1.4.0 com.alibaba.csp ahas-sentinel-client 1.0.4 com.alibaba.csp spring-boot-starter-ahas-sentinel-client 1.0.2
2.2 aop切入
//配置AOP切入 @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }
2.3 注解方式接入
@SentinelResource(value = "test") public void test() throws Exception { System.out.println("test!"); }
2.4 jvm参数配置
公网环境需要在阿里云ahas控制台获取许可证
公网环境需要在阿里云ahas控制台获取许可证
公网环境需要在阿里云ahas控制台获取许可证
#公网环境许可证 -Dahas.license=XXXXXX #调用apollo环境 -Denv=DEV #apollo服务地址 -Dapollo.configService=http://localhost:XXXX
2.5 限流规则编写
直接去ahas控制台对应用进行设置
访问localhost:XXXX/test 进行测试
3.根据调用方限流
3.1 场景:根据调用方标识分别做限流
ContextUtil.enter(resourceName, origin)
方法中的 origin
参数标明了调用方身份。这些信息会在 ClusterBuilderSlot
中被统计
注意:ContextUtil.enter(xxx)
方法仅在调用链路入口处生效
//controller层 @GetMapping("/test") public String foo(String origin) throws Exception { service.test(); ContextUtil.enter("test", origin); return service.hello(origin); } //service层 @SentinelResource(value = "test") public String hello(String origin) { return String.format(origin); }
3.2 查看调用方限流情况
访问:http://localhost:8719/origin?id=test
id: test idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total 1 test01 0 0 0 0 0 0 0 0 2 test02 0 0 0 0 0 0 0 0
上面这个命令展示了资源名为 test的资源被两个不同的调用方调用的统计。
四、sentinel参考资料
1.sentinel:https://github.com/alibaba/Sentinel
2.apollo:https://github.com/ctripcorp/apollo
3.阿里云AHAS:https://help.aliyun.com/product/87450.html
4.AHAS阿里云控制台:https://ahas.console.aliyun.com