sentinel 是什么
Sentinel 是面向分布式服务架构的轻量级流量控制框架,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。
sentinel 基本概念
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。
sentinel 功能和设计理念
流量控制
对系统来说,任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。
sentinel 流量控制有一下几个角度:
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
- 运行指标,例如 QPS、线程池、系统负载等;
- 控制的效果,例如直接限流、冷启动、排队等。
熔断降级
在微服务中,由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,比如服务超时,会导致请求发生堆积,长时间占用系统资源,最终会导致其他正常服务也不可用,导致整个系统的雪崩。熔断降级就是当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败。
sentinel 熔断的两种方式:
- 通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。 - 通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
系统负载保护
Sentinel 同时对系统的维度提供保护。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
sentinel 的使用
使用 Sentinel 来进行资源保护,主要分为两个步骤:
1.定义资源
2.定义规则
定义资源
抛出异常的方式定义资源
Entry entry = null;
// 务必保证finally会被执行
try {
// 资源名可使用任意有业务语义的字符串
entry = SphU.entry("自定义资源名");
/**
* 被保护的业务逻辑
*/
} catch (BlockException e1) {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
} finally {
if (entry != null) {
entry.exit();
}
}
返回布尔值方式定义资源
// 资源名可使用任意有业务语义的字符串
if (SphO.entry("自定义资源名")) {
// 务必保证finally会被执行
try {
/**
* 被保护的业务逻辑
*/
} finally {
SphO.exit();
}
} else {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
}
注解方式定义资源
Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandler 和 fallback 函数。
规则定义
Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则 以及 授权规则。
流量规则的定义
属性 | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 限流阈值 | |
grade | 限流阈值类型,是按照 QPS 还是线程数 | QPS 模式 |
limitApp | 是否根据调用者来限流 | 否 |
strategy | 判断的根据是资源自身,还是根据其它资源 (refResource),还是根据链路入口 (refResource) | 根据资源本身 |
controlBehavior | 发生拦截后的流量整形和控制策略(直接拒绝 / 排队等待 / 慢启动模式) | 直接拒绝 |
硬编码的方式定义流量控制规则实例:
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);
}
熔断降级规则 (DegradeRule)
属性 | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 熔断阈值 | |
grade | 降级模式,根据 RT 降级还是根据异常比例降级 | RT |
timeWindow | 降级的时间 |
硬编码的方式定义流量控制规则实例:
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)
属性 | 说明 | 默认值 |
---|---|---|
highestSystemLoad | 最大的 load1,参考值 | -1 (不生效) |
avgRt | 所有入口流量的平均响应时间 | -1 (不生效) |
grade | 降级模式,根据 RT 降级还是根据异常比例降级 | RT |
maxThread | 入口流量的最大并发数 | -1 (不生效) |
用硬编码的方式定义流量控制规则的实例:
private void initSystemProtectionRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}