4、如何使用Sentinel
4.1 简介
我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用Sentinel 来进行资源保护,主要分为两个步骤:
- 定义资源
- 定义规则
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
对于主流的框架,我们提供适配,只需要按照适配中的说明配置,Sentinel 就会默认定义提供的服务,方法等为资源。
4.2 定义资源
4.2.1 抛出异常的方式定义资源
用这种方式,当资源发生了限流之后会抛出BlockException。这个时候可以捕捉异常,进行限流之后的逻辑处理。示例代码如下:
代码语言:javascript复制Entry entry = null;
// 务必保证finally 会被执行
try {
// 资源名可使用任意有业务语义的字符串
entry = SphU.entry("自定义资源名");
/**
* 被保护的业务逻辑
*/
} catch (BlockException e1) {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
} finally {
if (entry != null) {
entry.exit();
}
}
4.2.2 返回布尔值方式定义资源
用这种方式,当资源发生了限流之后会返回false,这个时候可以根据返回值,进行限流之后的逻辑处理。示例代码如下:
代码语言:javascript复制 // 资源名可使用任意有业务语义的字符串
if (SphO.entry("自定义资源名")) {
// 务必保证finally 会被执行
try {
/**
* 被保护的业务逻辑
*/
} finally {
SphO.exit();
}
} else {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
}
4.2.3 判断限流降级异常
通过以下方法判断:
代码语言:javascript复制BlockException.isBlockException(Throwable t);
4.3 主流框架的适配
为了减少开发的复杂程度,我们对大部分的主流框架,例如Dubbo, RocketMQ,Spring Cloud 等都做了适配。您只需要引入对应的依赖,它们的方法,服务,都会进行默认的埋点。
参见: 主流框架的适配
4.4 定义规则
Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时Sentinel 也提供相关API,供您来定制自己的规则策略。
4.4.1 规则的定义
Sentinel 支持三种规则:流量控制规则、熔断降级规则以及系统保护规则。
4.4.2 流量控制规则(FlowRule)
- 流量规则的定义
- 通过代码定义流量控制规则 理解上面规则的定义之后,我们可以通过调用FlowRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则,比如:
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
rule1.setResource(KEY);
// set limit qps to 20
rule1.setCount(20);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
更多详细内容可以参考流量控制。
4.4.3 熔断降级规则(DegradeRule)
熔断降级规则包含下面几个重要的属性:
同一个资源可以同时有多个降级规则。 理解上面规则的定义之后,我们可以通过调用DegradeRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则。
代码语言:javascript复制 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);
}
更多详情可以参考熔断降级。
4.4.4 系统保护规则(SystemRule)
规则包含下面几个重要的属性:
理解上面规则的定义之后,我们可以通过调用SystemRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则。
代码语言:javascript复制 private void initSystemProtectionRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}
更多详情可以参考系统负载保护。
4.4.5 查询更改规则
运行下面命令,则会返回现有生效的规则:
代码语言:javascript复制curl http://localhost:8719/getRules?type=<XXXX>
其中,type=flow 以JSON 格式返回现有的限流规则;degrade 则返回现有生效的降级规则列表;system 则返回系统保护规则。
同时也可以通过下面命令来修改已有规则:
代码语言:javascript复制curl http://localhost:8719/setRules?type=<XXXX>&data=<DATA>
其中,type 可以输入flow、degrade 等方式来制定更改的规则种类,data 则是对应的JSON 格式的规则。
4.5 定制自己的持久化规则
上面的规则配置,都是存在内存中的。即如果应用重启,这个规则就会失效。因此我们提供了开放的接口,您可以通过实现DataSource 接口的方式,来自定义规则的存储数据源。通常我们的建议有:
- 整合动态配置系统,如etcd、Nacos,动态地实时刷新配置规则
- 结合DB、VCS 等来实现该规则
- 配合Sentinel Dashboard 使用
更多详情请参考动态规则配置。
4.6 规则生效的效果
除了在业务代码逻辑上看到规则生效,我们也可以通过下面简单的方法,来校验规则生效的效果:
- 暴露的HTTP 接口:通过运行下面命令
curl http://localhost:8719/cnode?id=<资源名称>
,观察返回的数据。如果规则生效,在返回的数据栏中的block 以及block(m) 中会有显示 - 日志:Sentinel 提供秒级的资源运行日志以及限流日志,详情可以参考: 日志