文章目录
- 前言
- [一、客户端与Spring Boot整合](#一、客户端与Spring Boot整合)
- 二、SphU.entry
- 总结
前言
Sentinel作为Spring cloud alibaba中流控的组件,在微服务架构中也有广泛的应用。其核心源码主要体现在客户端。客户端在启动时,和Nacos类似,也会将自己的信息注册到服务端。而服务端的页面上配置各种规则时,实际上也是将信息发送到了客户端。
我们最常使用的@SentinelResource
注解:
底层也是基于AOP + 责任链模式实现的。**Sentinel的难点不在于处理流程,而在于限流的算法。**本篇仅介绍Sentinel责任链的核心流程。
一、客户端与Spring Boot整合
在Spring Boot项目中,如果需要引入Sentinel,通常需要在pom文件中加入:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
该组件也是利用了Spring Boot的自动配置:
其中的SentinelAutoConfiguration
是核心:
在SentinelAutoConfiguration
中,会注册SentinelResourceAspect
Bean:
SentinelResourceAspect
实际上是一个切面,匹配了所有加入了@SentinelResource
注解的方法:
invokeResourceWithSentinel
是一个环绕通知。 。在执行目标方法之前,首先会得到目标方法对象,以及处理注解中的一些信息,然后调用SphU.entry
方法。该方法是Sentinel流程的核心。
点击进去,会调用到entry
方法:
Env在实例化之前,会触发static
中的逻辑:
在doInit
方法中,又会通过SPI机制,加载InitFunc
中的类:
其中的HeartbeatSenderInitFunc
是定期向服务端发送心跳的:
CommandCenterInitFunc
,是将客户端各种接收规则的接口信息,暴露给服务端:
上面的逻辑,包括后续构建,执行责任链,是在切面中,并非是在应用启动时执行的,而是在执行加入了@SentinelResource
注解的方法时才会去执行!
二、SphU.entry
SphU.entry
方法内部主要做了两件事:
- 构建责任链。
- 按照顺序依次调用责任链。

2.1、构建责任链
在进入lookProcessChain
方法后,首先通过双检锁模式,判断当前加入了@SentinelResource
注解的方法,是否已经为其构建过责任链,如果没有,才会执行newSlotChain
方法。也就是说,是每一个加入了注解的方法,都有一个对应的责任链,并且只在应用启动后该方法第一次被调用时初始化。
最终调用的是DefaultSlotChainBuilder
的build
方法:
在该方法中,主要做了两件事:
通过SPI机制,加载ProcessorSlots
文件中的类(责任链中的具体组成类)。

真正地去构建责任链:在执行ProcessorSlotChain chain = new DefaultProcessorSlotChain();
这一段代码时,实际上是构造了:
构造出的是下图的数据结构,end是指向first的引用:
在构造完成后,就会利用chain.addLast((AbstractLinkedProcessorSlot<?>) slot);
方法,向上图的数据结构中插入具体的责任链类了:
首先将end的next指针指向NodeSelectorSlot,因为end是指向指向first的引用,实际上first的next指针也指向了NodeSelectorSlot:
然后将end指向NodeSelectorSlot:
以此类推,最终构建出的责任链是:
图片来源:图灵学院
2.2、调用责任链
这里我们重点关注FlowSlot和DegradeSlot
,它们是sentinel核心功能-限流熔断降级的体现。
2.2.1、NodeSelectorSlot
首先调用的是NodeSelectorSlot
,它的作用是构建资源调用的统计节点,用于记录调用链路信息,并且将资源关联到相应的 DefaultNode。
fireEntry
就是在满足条件的情况下,继续调用后续的责任链。
2.2.2、ClusterBuilderSlot
ClusterBuilderSlot
和NodeSelectorSlot
是类似的,它的作用是构建统计节点的聚合关系。但是NodeSelectorSlot 是按调用链统计,ClusterBuilderSlot 是按资源维度统计。
2.2.3、LogSlot
LogSlot
的作用,是在后续的责任链调用过程中出现异常时,进行日志的记录,体现在它的try...catch中:
2.2.4、StatisticSlot
StatisticSlot
是先将请求放行到后续的责任链,在后续的责任链调用完成后,再去进行统计资源的调用情况的操作。例如记录 QPS(每秒请求数)、RT(响应时间)、线程数、异常数等。
包括抛出了各种异常之后的记录,这些记录都是执行降级、限流等控制的基础数据来源。
2.2.5、AuthoritySlot
AuthoritySlot
是进行授权规则的检查,例如黑白名单:
简单回顾一下黑白名单的使用,首先需要在sentinel控制台的授权规则选项卡
进行配置:
这里的资源名
,是http请求的路径,而流控应用
,可以是特定的ip,也可以是请求路径:
java
@Component
public class IPLimiter implements RequestOriginParser {
/**
* 获取当前服务实例的ip
*/
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
return httpServletRequest.getRemoteAddr();
}
}
在checkBlackWhiteAuthority
方法中,首先会获取所有设置的规则,然后根据当前的资源名,获取该资源对应的所有规则
然后进行检查:
这里的黑白名单体现在RuleConstant
这个常量类中:
判断逻辑有点绕:
- 如果规则中的IP或路径,和请求中的匹配,contain会为true,反之为false。
- 在黑名单的判定中,如果contain为true,则返回false,代表请求不通过。因为黑名单就是要对能和规则匹配上的请求进行拦截。
- 在白名单的判断中,如果contain为false,则返回false,代表请求不通过。因为contain为false,代表请求和规则匹配不上,也就是不在白名单中。

2.2.6、SystemSlot
SystemSlot
是对系统规则进行控制,包括系统整体的 QPS,平均响应时间(RT),当前系统的并发线程数等。
2.2.7、FlowSlot
FlowSlot
是 Sentinel 的核心功能之一,用于流量控制(限流)规则判断。
同样会获取到控制台设置的所有规则,然后逐个进行匹配:
最终调用到的是passLocalCheck
,其中也有两个关键方法:
2.2.7.1、selectNodeByRequesterAndStrategy
selectNodeByRequesterAndStrategy
用于在执行限流时 选择哪个节点(Node)来做统计和判断。不同的来源(origin)和限流策略(strategy)决定了限流数据统计的维度。首先会获取到流控模式,也就是控制台设置的:
- 匹配指定 origin 的限流
- 如果是
直接模式
,就利用context.getOriginNode();
调用方自己的统计节点限流。 - 如果是其他策略,利用
selectReferenceNode
再次匹配:
- 如果是

- 如果来源是
default
:- 直接限流时,使用当前资源的全局统计节点
- 非直接限流,使用关联资源的统计节点。
- 如果来源是
other
:- 直接限流时,使用当前资源的全局统计节点
- 非直接限流,使用关联资源的统计节点。
2.2.7.2、canPass
在拿到上一步推断出的节点后,会调用canPass方法,这里的canPass也有不同的实现:
对应控制台中的:
这里涉及到滑动窗口,令牌桶,漏桶算法,会在后续进行说明。 Sentinel的难点不在于流程,而是算法。
2.2.8、DegradeSlot
DegradeSlot
的作用是熔断降级控制。也是 Sentinel 的核心功能之一:
在tryPass
方法中,会对逐条规则进行校验,如果此时的断路器处于打开状态,
并且超过了熔断时间,会修改状态为半开
。
熔断降级中有一个重要的概念,也就是断路器
。在Sentinel 1.8 版本之后,断路器有三种状态,都记录在CircuitBreaker
的内部State
枚举类中:
在这里简单的说一下三种状态的转换:
- 正常情况下,断路器处于
关闭
状态,所有请求正常通过。 - 当请求触发了降级条件(如异常比例过高、RT过大) 后,断路器会进入
打开
状态,在接下来的熔断时长内(如 10 秒),所有请求都被拒绝(降级)。 - 当熔断时长结束后,下一个请求到达时,断路器进入
半开
状态:- 如果该请求再次触发降级条件,断路器重新回到
打开
状态。 - 如果该请求通过且正常,断路器会恢复为
关闭
状态。
- 如果该请求再次触发降级条件,断路器重新回到
Closed → [触发降级条件] → Open → [熔断时长结束,下一请求] → Half-Open
↑ ↓
└────── [探测失败] ←──── [探测成功] ←──────────────┘
总结
本篇介绍了Sentinel 实现控制台功能,在服务端的实现原理:通过AOP + 责任链模式实现。并且在调用目标方法时,为每一个请求都创建一份责任链,放入缓存,依次调用。
后面几个责任链的实现,在规则校验不通过时,都会抛出异常 ,而真正处理的逻辑,在StatisticSlot
的catch中,以及SentinelResourceAspect#invokeResourceWithSentinel
的entry.exit
中,包括处理断路器的状态。
下一篇:Sentinel核心源码分析(下)