SpringCloud Alibaba (三):Sentinel 流量控制组件
SpringCloud Alibaba (三):Sentinel 流量控制组件
Sentinel 是什么
Sentinel 基本概念
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
规则的种类
Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略。
Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
流量控制规则 (FlowRule)
流量规则的定义0
重要属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 限流阈值 | |
grade | 限流阈值类型,QPS 或线程数模式 | QPS 模式 |
limitApp | 流控针对的调用来源 | default ,代表不区分调用来源 |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 | 直接拒绝 |
同一个资源可以同时有多个限流规则。
通过代码定义流量控制规则
理解上面规则的定义之后,我们可以通过调用 FlowRuleManager.loadRules()
方法来用硬编码的方式定义流量控制规则,比如:
private static void initFlowQpsRule() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule1 = new FlowRule(); rule1.setResource(resource); // Set max qps to 20 rule1.setCount(20); rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setLimitApp("default"); rules.add(rule1); FlowRuleManager.loadRules(rules); }
更多详细内容可以参考 流量控制。
熔断降级规则包含下面几个重要的属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,即限流规则的作用对象 | |
count | 阈值 | |
grade | 熔断策略,支持秒级 RT/秒级异常比例/分钟级异常数 | 秒级平均 RT |
timeWindow | 降级的时间,单位为 s |
同一个资源可以同时有多个降级规则。
理解上面规则的定义之后,我们可以通过调用 DegradeRuleManager.loadRules()
方法来用硬编码的方式定义流量控制规则。
private static void initDegradeRule() { List<DegradeRule> rules = new ArrayList<>(); DegradeRule rule = new DegradeRule(); rule.setResource(KEY); // set threshold rt, 10 ms rule.setCount(10); rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); rule.setTimeWindow(10); rules.add(rule); DegradeRuleManager.loadRules(rules); }
更多详情可以参考 熔断降级。
系统保护规则 (SystemRule)
规则包含下面几个重要的属性:
Field | 说明 | 默认值 |
---|---|---|
load1 阈值,参考值 |
-1 (不生效) | |
avgRt | -1 (不生效) | |
maxThread | 入口流量的最大并发数 | -1 (不生效) |
qps | 所有入口资源的 QPS | -1 (不生效) |
highestCpuUsage | 当前系统的 CPU 使用率(0.0-1.0) | -1 (不生效) |
理解上面规则的定义之后,我们可以通过调用 SystemRuleManager.loadRules()
方法来用硬编码的方式定义流量控制规则。
private void initSystemProtectionRule() { List<SystemRule> rules = new ArrayList<>(); SystemRule rule = new SystemRule(); rule.setHighestSystemLoad(10); rules.add(rule); SystemRuleManager.loadRules(rules); }
更多详情可以参考 系统自适应保护。
访问控制规则 (AuthorityRule)
很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的访问控制(黑白名单)的功能。黑白名单根据资源的请求来源(origin
)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
授权规则,即黑白名单规则(AuthorityRule
)非常简单,主要有以下配置项:
-
resource
:资源名,即限流规则的作用对象 -
limitApp
:对应的黑名单/白名单,不同 origin 用,
分隔,如appA,appB
-
strategy
:限制模式,AUTHORITY_WHITE
为白名单模式,AUTHORITY_BLACK
为黑名单模式,默认为白名单模式
更多详情可以参考 来源访问控制。
热点规则 (ParamFlowRule)
详情可以参考 热点参数限流。
Sentinel控制台
概述
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。另外,鉴权在生产环境中也必不可少。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。
接下来,我们将会逐一介绍如何整合 Sentinel 核心库和 Dashboard,让它发挥最大的作用。同时我们也在阿里云上提供企业级的控制台:AHAS Sentinel 控制台,您只需要几个简单的步骤,就能最直观地看到控制台如何实现这些功能。
Sentinel 控制台包含如下功能:
-
查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
-
监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
-
规则管理和推送:统一管理推送规则。
-
鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
更详细内容,访问 https://github.com/alibaba/Sentinel/wiki
启动Sentinel控制台
1.在Sentinel的github上下载 sentinel-dashboard.jar
https://github.com/alibaba/Sentinel/releases
2.在sentinel-dashboard.jar所在文件夹运行cmd,在cmd里运行以下启动命令启动sentinel-dashboard
java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar
3.访问 localhost:8081,进入Sentinel控制台,默认用户和密码都是 sentinel
SpringCloud Alibaba 整合 Sentinel
Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果。
我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:
-
定义资源
-
定义规则
-
检验规则是否生效
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
定义资源
1. 添加依赖
注意:在整合spring-cloud-starter-alibaba-sentinel
和spring-cloud-starter-openfeign
时,feign-core的版本要在10.1.0以上,即导入2.1.0.RELEASE或以上版本的openfeign,否则会报feign.RequestTemplate.path()Ljava/lang/String;异常
,因为低版本openfeign的RequestTemplate类里没有path方法
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.1.0.RELEASE</version> </dependency>
server:
port: 8080
spring:
application:
name: consumer-8080
cloud:
nacos:
discovery:
server-addr: 192.168.11.132:8848
sentinel:
transport:
dashboard: localhost:8081 # 将服务注册到sentinel控制台
feign:
sentinel:
enabled: true #开启feign的sentinel支持
management:
endpoints:
web:
exposure:
include: "*"
3.在controller需要保护的方法添加 @SentinelResource 注解,把方法定义为资源
@RestController public class FeignController { @Autowired private EchoService echoService; @SentinelResource(value = "echo", blockHandler = "echoBlockHandler", blockHandlerClass = EchoServiceBlockHandler.class) @GetMapping("/feign/echo/{string}") public String echo(@PathVariable("string")String string){ return echoService.echo(string); } }
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource
注解包含以下属性:
-
value
:资源名称,必需项(不能为空) -
entryType
:entry 类型,可选项(默认为EntryType.OUT
) -
blockHandler
/blockHandlerClass
:blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。 -
fallback
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:-
返回值类型必须与原函数返回值类型一致;
-
方法参数列表需要和原函数一致,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。 -
fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
-
-
defaultFallback
(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:-
返回值类型必须与原函数返回值类型一致。
-
方法参数列表需要为空,或者可以额外多一个
Throwable
类型的参数用于接收对应的异常。 -
defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定
fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。
-
-
exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
blockHandler 和 fallback区别:
blockHandler
函数会在原方法被限流/降级/系统保护的时候调用,而 fallback
函数会针对所有类型的异常。
如果一个资源同时对 blockHandler 和 fallback 都进行了配置,除了流量控制规则触发时抛出的 BlockException
会进入 blockHandler
处理逻辑,其他规则触发时都会进入fallback
处理逻辑
4.创建EchoServiceBlockHandler类,建立blockHandler 处理逻辑
public class EchoServiceBlockHandler { private final static Logger logger = LoggerFactory.getLogger(EchoServiceBlockHandler.class); public static String echoBlockHandler(String string, BlockException e){ logger.error("error: "+e); return "方法请求降级中"; } }
在应用程序里定义规则
1.在启动类中定义规则,并加入容器中
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class Consumer8080 { public static void main(String[] args) { SpringApplication.run(Consumer8080.class, args); } @Bean public SentinelResourceAspect sentinelResourceAspect(){ return new SentinelResourceAspect(); } //流量控制规则 @Bean public static void initFlowRule(){ List<FlowRule> rules = new ArrayList<FlowRule>(); FlowRule flowRule = new FlowRule(); flowRule.setResource("echo"); //设置资源名,即流量控制规则的作用对象 flowRule.setCount(2); //设置限流阈值,此为QPS,即每秒最高访问量 flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); //限流阈值类型,QPS或线程数 rules.add(flowRule); FlowRuleManager.loadRules(rules); } }
2.访问测试
访问 http://localhost:8080/feign/echo/hi ,快速刷新,触发流量控制规则,调用降级逻辑
在Sentinel控制台定义规则
在Sentinel控制台上我们可以简单、灵活地管理规则以及推送规则,但是要注意的是,在Sentinel控制台上定义的规则是不会被持久化的,仅在内存中生存,当你重启应用时,在Sentinel控制台上定义的规则将会丢失(应用程序里定义的规则在sentinel控制台上删除,应用重启后会重新生效)
翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 谷歌翻译(国内) 译