Sentinel 是怎么实现限流的?

Sherwin.Wei Lv7

Sentinel 是怎么实现限流的?

回答重点

首先需要定义具体需要限流的资源,然后指定一定的规则(基于QPS(每秒查询数)、线程数等维度),限制资源的访问频次。

然后根据一定的限流算法(固定窗口、滑动窗口、令牌桶和漏桶),对指定的资源进行访问的流量控制。

具体流程如下:

  1. 当一个请求进入系统时,Sentinel 会首先对请求进行统计(如当前的 QPS、并发数)
  2. 接着 Sentinel 检查配置的限流规则,如果当前请求的速率超过了设定的限流阈值,Sentinel 将触发限流措施。
  3. 对于被限流的请求,可以选择直接拒绝、排队等待、或返回降级响应等方式来处理,保证系统核心功能的稳定。

扩展知识

Sentinel 使用限流流程

1) 资源定义

在 Sentinel 中,一个服务甚至一段代码都可以看作资源,在实现限流之前,需要先明确限流的对象,即限流的资源,接口,方法都是可以的,如下所示:

1
2
3
4
5
6
7
8
9
10
/ 原本的业务方法.
@SentinelResource(blockHandler = "blockHandlerForGetTest")
public Test getTestByid(String id) {
throw new RuntimeException("geTestByid command failed");
}

// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public Test blockHandlerForGetTest(String id, BlockException ex) {
return new Test("Test");
}

2)配置限流规则

在 Sentinel 配置文件中配置资源的限流规则,可以是资源名称、限流阈值等等,如下示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule0 = new FlowRule();
rule1.setResource(resource);
// Set max qps to 20
rule1.setCount(20);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);

rule1.setLimitApp("default");
rules.add(rule0);
FlowRuleManager.loadRules(rules);
}

3)流量监控

Sntinel 会监控资源的流量情况,如请求的 QPS、线程数、响应时间等等。

Snipaste_2024-06-13_05-01-03.jpg

4)限流控制

这里放一张官方文档的图片,如下所示,当请求到达之后,Sentinel 会根据资源的限流规则结合当前资源的情况,判定是否需要对服务进行限流控制,如果请求超过了限流规则的阈值,则会对服务采取限流、熔断或者降级处理。

ec903e569092136bb03d9e3a89e40474.png

限流的策略与执行

直接拒绝

  • 策略:当请求超过限流阈值时,Sentinel 会直接拒绝多余的请求,并返回错误响应或提示信息。该策略适用于对延迟敏感且无需等待的业务。
  • 应用场景:如 API 网关层面的流量控制,当接口 QPS 达到限制时,直接返回 HTTP 429(Too Many Requests)。

排队等待

  • 策略:对于部分请求,Sentinel 允许其进入排队等待,排队时间不超过设定的超时时间时,仍然可以通过请求。排队等待机制类似于漏桶算法
  • 应用场景:适用于需要一定请求延迟容忍度的业务场景,如异步处理任务或批量数据导入。

关联限流

  • 策略:在关联限流中,Sentinel 允许根据另一个资源的状态来限流当前资源。例如,可以基于主服务的 QPS 阈值来限制附属服务的调用。

  • 应用场景:适用于多个服务之间存在强关联的场景,如当订单服务的流量超过一定阈值时,限制推荐服务的请求。

    • 链路限流
      • 策略:链路限流是针对调用链路的限流策略,它允许基于调用链路的不同来源进行限流。通过这种方式,可以更精细地控制不同来源请求的流量。
      • 应用场景:适用于微服务调用链复杂的场景,可以对不同的调用链来源分别设置限流策略,以避免流量集中在某个节点。

Sentinel 限流的核心组件

Slot Chain(槽链)

  • 定义:Sentinel 中的核心限流逻辑是通过 Slot Chain 来实现的。Slot Chain 是一个拦截器链,它在每个请求进入时执行链中的各个槽位,依次进行流控、熔断、降级等操作。
  • 执行流程:当请求进入时,Slot Chain 会根据限流规则检查当前请求是否可以通过。如果某个槽位(如流控槽)检查到请求超过了设定的限流阈值,则会直接触发限流操作。

Flow Slot(流控槽)

  • 定义:Flow Slot 是 Slot Chain 中负责流控的部分,它根据预设的限流规则来检查请求的速率和并发数。
  • 作用:Flow Slot 会根据限流规则中的 QPS 阈值或并发数限制,判断是否允许请求通过。它是实现流量控制的关键组件。

Statistic Node(统计节点)

  • 定义:Sentinel 使用 Statistic Node 来记录每个资源的请求统计信息,包括通过数、阻塞数、QPS、响应时间等。
  • 作用:统计节点为限流决策提供了数据支持,帮助 Flow Slot 在限流时做出精确的判断。

Sentinel 常用的限流规则配置

按 QPS 限流

  • 定义:限制每秒允许的最大请求数,当请求量超过设定的 QPS 时,触发限流策略。
  • 配置示例
    1
    2
    3
    4
    FlowRule flowRule = new FlowRule();
    flowRule.setResource("resourceName");
    flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    flowRule.setCount(100); // 最大 QPS 为 100

按线程数限流

  • 定义:限制当前正在处理的请求的并发线程数,如果并发线程数超过设定的阈值,触发限流。
  • 配置示例
    1
    2
    3
    4
    FlowRule flowRule = new FlowRule();
    flowRule.setResource("resourceName");
    flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
    flowRule.setCount(10); // 最大并发线程数为 10

按调用关系限流

  • 定义:可以对不同调用链进行限流,比如在不同的调用来源下设置不同的限流规则,以保证某些关键链路的稳定性。
  • 配置示例
    1
    2
    3
    4
    FlowRule flowRule = new FlowRule();
    flowRule.setResource("resourceName");
    flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
    flowRule.setRefResource("parentResource");
Comments