Sentinel源码分析

2 篇文章 0 订阅
2 篇文章 0 订阅

Sentinel的基本概念

Sentinel实现限流、隔离、降级、熔断等功能,本质是做了两件事:

  • 统计数据:统计某资源访问数据(QPS、RT等)。
  • 规则判断:判断限流规则时、隔离规则、降级规则、熔断规则是否满足。
    这里的资源就是希望被Sentinel保护的业务,如项目中Controller方法就是默认被Sentinel保护的资源。

ProcessorSlotChain

Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起。slot chain 其实可以分为两部分:统计数据构建部分(statistic)和判断部分(rule checking)。核心结构:
核心结构

责任链中的slot也分为两大类:

  • 统计数据构建部分(statistic)
  • NodeSelectorSlot:负责构建簇点链路中的节点(DefaultNode),将这些节点形成链路树
  • ClusterBuilderSlot:负责构建某个资源的ClusterNode,ClusterNode可以保存资源的运行信息(响应时间、QPS、block数据、线程数、异常数等)以及来源信息(origin名称)
  • StatisticSlot:负责统计实时调用数据,包括运行信息、来源信息等
  • 规则判断部分(rule checking)
  • AuthoritySlot:负责授权规则(来源控制)
  • SystemSlot:负责系统保护规则
  • ParamFlowSlot:负责热点参数限流规则
  • FlowSlot:负责限流规则
  • DegradeSlot:负责降级规则

Node

Sentinel 里面的各种种类的统计节点:

统计节点

所有的节点都可以记录对资源的访问统计数据,所以都是StatisticNode的子类。

按照作用分为两类Node:

  • DefaultNode:代表链路树中的每个资源,一个资源出现在不同的链路中时,会创建不同的DefaultNode节点。而树的入口节点叫EntranceNode,是一种特殊的DefaultNode
  • ClusterNode:代表资源,一个资源不管出现在多少个链路中,只会有一个ClusterNode。记录的是当前资源被访问的所有数据之和。

DefaultNode记录的是资源在当前链路中的访问数据,用来实现基于链路模式的先流规则。ClusterNode记录的是资源的所有链路的访问数据,实现默认模式、关联模式的先流规则。

例如:造一个MVC项目中,有两个业务:

  • 业务1:controller中的资源/order/query访问service中的资源/goods
  • 业务2:controller中的资源/order/save访问service中的资源/goods

创建的链路图如下:

链路图

Entry

默认情况下,Sentinel会将Controller中的方法作为被保护的资源,如果要将自己的代码标记为Sentinel的资源,则需要声明Entry,示例如下:

  • 引入依赖
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • 配置Sentinel地址
spring:
	  cloud:
		  sentinel:
				transport:
					dashboard: localhost:8080
  • 编写代码
try (Entry login = SphU.entry("login")) {
	// 业务代码
} catch (BlockException e) {
	return "被限流";
}
  • 注解方式实现:
    @SentinelResource("login")

@SentinelResource注解基于AOP思想,对加注解的方法进行环绕增强,完成资源(Entry)的创建。

Context

进入控制台我们发现,簇点链路中除了我们写的方法节点外,还有一个默认sentinel_spring_web_context节点,这是一个EntranceNode类型的节点,在初始化Context的时候有Sentinel创建的。

什么是Context

  • Context代表调用链路的上下文,贯穿一次调用链路中的所有资源(Entry),基于ThreadLocal实现。
  • Context维持着入口节点(EntraceNode)、本次调用链路的curNode(当前资源节点)、调用来源(origin)等信息。
  • 后续的Slot都可以通过Context拿到DefaultNode或者ClusterNode,从而获取统计数据,完成规则判断。
  • Context初始化的过程中,会创建EntraceNode、contextName就是EntraceNode的名称

对应API如下:

ContextUtil.entry("contextName", "originName");

Context初始化

自动装配 spring.factories声明需要自动装配的类

自动装配类

首先我们看SentinelWebAutoConfiguration类:

SentinelWebAutoConfiguration

AbstractSentinelInterceptor

AbstractSentinelInterceptor

ContextUtil

ContextUtil

ProcessorSlotChain执行流程

入口

回到入口,AbstractSentinelInterceptor类的preHandle方法(见上图);以及SentinelResourceAspect的环绕增强方法:

源码

可以看到,任何资源必须执行SphU.entry()方法,我们跟踪此方法找到真实创建的方法:

源码

源码

源码

源码

DefaultProcessorSlotChain

源码

NodeSelectorSlot

NodeSelectorSlot负责构建簇点链路中的节点(DefaultNode),将这些节点形成链路树

源码

ClusterBuilderSlot

ClusterBuilderSlot 负责构建某个资源的ClusterNode

源码

LogSlot

除了记录异常日志外,啥都没干

StatisticSlot

StatisticSlot负责统计调用数据,包含访问次数、线程数、来源信息等。
StatisticSlot是实现限流的关键,基于滑动时间窗口算法维护计数器来统计进入某个资源的请求次数,用于后面的降级限流使用。

源码

AuthoritySlot

根据黑白名单和来源来判断是否授权

源码

源码

SystemSlot

源码

ParamFlowSlot

源码

源码

FlowSlot

滑动时间窗口(预热或直接拒绝)

滑动时间窗口算法这里用的是一个环形数组来统计当前时间窗口的QPS数据,比如每个窗口时间为1s,将窗口分割为2个区间,则每个区间时间间隔为500ms,当窗口区间分割越多,统计数据越精确,但复杂度越高。

滑动时间窗口

源码

源码

源码

源码

源码

源码

漏桶(排队等候)

源码

让所有请求进入队列中,再根据阈值设置的时间间隔依次放行。流量稳定,起到流量削峰的作用。但如果等待时间超出最大等待时常,说明流量过载,直接拒绝。

DegradeSlot

前面我们讲过降级机制是基于状态机制实现的:

状态机

源码

源码

源码

源码

源码
访问我的博客查看更多文章

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值