---
url: /java/Sentinel.md
---
# Sentinel 架构与实现原理

## 概述

Sentinel 是一个专注于**流量控制、熔断降级、系统负载保护**的分布式系统流控防护组件。它提供了一套完整的高可用解决方案，帮助微服务系统在复杂多变的环境中保持稳定运行。

**来源**: https://github.com/alibaba/sentinel

***

## 核心架构设计

### 1. SlotChain 责任链模式

Sentinel 的核心架构采用了**责任链模式（Slot Chain Pattern）**，这是其最核心的设计思想。

```
Entry -> SlotChain -> [多个 Slot] -> Exit
```

#### SlotChain 工作流程

每个请求进入 Sentinel 保护的资源时，会经过一个由多个 `Slot` 组成的责任链：

```
SlotChain
├── ClusterStateSlot        // 集群流控状态
├── SystemRuleSlot          // 系统规则检查
├── FlowControlSlot         // 流控检查
├── DegradeSlot             // 熔断降级检查
├── AuthoritySlot           // 授权检查
├── ParameterLimitSlot      // 参数字段限流
├── ClusterFlowSlot         // 集群流控
├── AdapterLinkSlot         // 适配链接
├── MetricSlot              // 指标统计
└── DefaultControlSlot      // 默认处理
```

#### Processor 接口

每个 Slot 都实现了 `Processor` 接口：

```java
public interface Processor<R> {
    Entry processBefore(RequestNode node, int count, Context context) throws Exception;
    void processAfter(RequestNode node, int count, Context context);
    void onExit(ResourceWrapper wrapper, RequestNode node, Context context);
}
```

* **processBefore**: 在进入资源前执行，进行各种检查和判断
* **processAfter**: 在资源访问后执行，更新统计数据
* **onExit**: 在退出时执行，清理资源

**来源**: https://github.com/alibaba/sentinel/wiki/How-it-works

***

## 核心机制详解

### 2. 入口节点与调用树

Sentinel 通过 `ContextUtil.enter()` 和 `SphU.entry()` 构建内存中的调用树：

```java
// 定义调用链入口
ContextUtil.enter("entrance1", "appA");
// 进入资源
Entry nodeA = SphU.entry("nodeA");
try {
    // 业务逻辑
} finally {
    nodeA.exit();
}
ContextUtil.exit();
```

形成的调用树结构：

```
machine-root
     |
     EntranceNode1 (entrance1)
     |
     DefaultNode(nodeA)
```

**来源**: https://github.com/alibaba/sentinel/wiki/How-it-works

***

### 3. 流控机制（Flow Control）

#### 3.1 FlowRule 配置

```java
FlowRule rule = new FlowRule();
rule.setResource("my_resource");      // 资源名
rule.setCount(20);                    // 阈值
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS 模式
rule.setLimitApp("default");          // 调用来源
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 流控效果
```

#### 3.2 流控等级（grade）

| 类型 | 常量 | 说明 |
|------|------|------|
| 线程数 | FLOW_GRADE_THREAD | 基于并发线程数限制 |
| QPS | FLOW_GRADE_QPS | 基于每秒请求数限制 |

#### 3.3 流控策略（strategy）

| 策略 | 常量 | 说明 |
|------|------|------|
| 直接 | DIRECT | 针对资源本身进行流控 |
| 关联 | RELATE | 当关联资源达到阈值时触发 |
| 链路 | CHAIN | 仅对指定入口的调用进行流控 |

#### 3.4 流控效果（controlBehavior）

| 效果 | 常量 | 说明 |
|------|------|------|
| 快速失败 | CONTROL_BEHAVIOR_DEFAULT | 超出阈值立即拒绝 |
| WarmUp | CONTROL_BEHAVIOR_WARM_UP | 逐渐提升阈值（30 秒内从 1/3 到满额） |
| 匀速排队 | CONTROL_BEHAVIOR_RATE_LIMITER | 使用漏桶算法均匀放行 |

**示例 - 匀速流控**：

```java
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
rule.setCount(10);  // 10 QPS，平均 100ms 放行一个请求
rule.setMaxQueueingTimeMs(20 * 1000);  // 最大排队时间 20 秒
```

**来源**:

* https://github.com/alibaba/sentinel/wiki/Flow-Control
* https://github.com/alibaba/sentinel/wiki/流量控制
* https://github.com/alibaba/sentinel/wiki/Flow-Shaping:-Pace-Limiter

***

### 4. 熔断降级机制（Circuit Breaking）

#### 4.1 DegradeRule 配置

```java
DegradeRule rule = new DegradeRule();
rule.setResource("my_resource");
rule.setCount(10);              // 阈值
rule.setGrade(DEGRADE_GRADE_RT);// 慢调用比例
rule.setTimeWindow(10);         // 熔断时长 10 秒
rule.setMinRequestAmount(5);    // 最小请求数
rule.setStatIntervalMs(1000);   // 统计时长 1 秒
rule.setSlowRatioThreshold(0.3);// 慢调用比例阈值 30%
```

#### 4.2 熔断策略（grade）

| 策略 | 常量 | 说明 |
|------|------|------|
| 慢调用比例 | DEGRADE_GRADE_RT | RT 超过阈值的请求占比超过设定值时触发 |
| 异常比例 | DEGRADE_GRADE_EXCEPTION_RATIO | 异常请求占比超过阈值时触发 |
| 异常数 | DEGRADE_GRADE_EXCEPTION_COUNT | 单位时间内异常数量超过阈值时触发 |

#### 4.3 熔断状态机

```
关闭 (CLOSED) -> 打开 (OPEN) -> 半开 (HALF_OPEN) -> 关闭 (CLOSED)
```

* **CLOSED**: 正常状态，请求正常通过
* **OPEN**: 熔断状态，直接拒绝请求
* **HALF_OPEN**: 试探状态，允许少量请求通过测试服务是否恢复

**来源**:

* https://github.com/alibaba/sentinel/wiki/如何使用
* https://github.com/alibaba/sentinel/wiki/How-to-Use

***

### 5. 调用来源识别

通过 `ContextUtil.enter()` 标识调用方身份：

```java
// 标记资源名和调用方
ContextUtil.enter(resourceName, origin);
```

`limitApp` 取值说明：

| 值 | 说明 |
|----|------|
| default | 不区分调用方，对所有请求生效 |
| {origin 名称} | 仅对指定调用方的请求生效 |
| other | 对未明确定义的调用方生效 |

**来源**: https://github.com/alibaba/sentinel/wiki/流量控制

***

### 6. 集群流控（Cluster Flow Control）

集群流控允许多个服务实例共享流控额度，适用于需要全局统一控制的场景。

#### 扩展接口

```
通用接口:
├── TokenService          // 令牌服务接口
├── ClusterTokenClient    // 客户端接口
├── ClusterTokenServer    // 服务端接口
└── EmbeddedClusterTokenServer  // 嵌入式服务端

客户端扩展:
├── ClusterTransportClient  // 通信客户端
├── RequestEntityWriter     // 请求序列化
└── ResponseEntityDecoder   // 响应反序列化

服务端扩展:
├── ResponseEntityWriter   // 响应序列化
├── RequestEntityDecoder   // 请求反序列化
└── RequestProcessor       // 请求处理
```

**来源**: https://github.com/alibaba/sentinel/wiki/集群流控

***

## 统计机制

Sentinel 使用滑动窗口和原子操作来实现高性能的实时统计：

1. **LeakyBucket（漏桶）**: 用于匀速排队流控
2. **原子计数器**: 用于并发安全的计数统计
3. **分段滑动窗口**: 将时间划分为多个小窗口，精确统计各时段数据

***

## 总结

Sentinel 的核心设计理念：

1. **责任链模式（SlotChain）**: 灵活可扩展的架构
2. **多维度流控**: 支持 QPS、线程数、关联、链路等多种策略
3. **智能熔断**: 基于慢调用比例、异常比例的自动降级
4. **集群协同**: 跨实例的统一流控能力
5. **低侵入性**: 通过 AOP 和 SPI 集成各种框架

**主要来源**:

* https://github.com/alibaba/sentinel/wiki/Flow-Control
* https://github.com/alibaba/sentinel/wiki/流量控制
* https://github.com/alibaba/sentinel/wiki/How-it-works
* https://github.com/alibaba/sentinel/wiki/如何使用
* https://github.com/alibaba/sentinel/wiki/How-to-Use
* https://github.com/alibaba/sentinel/wiki/集群流控
* https://github.com/alibaba/sentinel/wiki/Flow-Shaping:-Pace-Limiter
