Sentinel 是如何实现分布式限流的?

2,939 阅读4分钟

hello,大家好,我是张张,「架构精进之路」公号作者。

随着近些年系统稳定性要求越来越高,限流是保障服务高可用的方式之一,尤其是在微服务架构中,对接口或资源进行限流可以有效地保障服务的可用性和稳定性。

在众多限流平台中 Sentinel 凭着丰富功能特性和多次阿里双十一的线上实践,成为最热门限流平台之一,Sentinel 是阿里巴巴提供的一种限流、熔断中间件,与RateLimiter相比,Sentinel提供了丰富的限流、熔断功能。它支持控制台配置限流、熔断规则,支持集群限流,并可以将相应服务调用情况可视化。

本文就Sentinel相关特性进行分析并测试并对底层原理进行分析,为后续相关系统建设积累经验。

一、总体流程

之前我们学习过限流比较主流的三种算法:漏桶,令牌桶,滑动窗口。而Sentinel采用的是最后一种,滑动窗口来实现限流的。

先来了解一下总体流程:

图片

上面的图是官网的图,从设计模式上来看,典型的的责任链模式。外部请求进来后,要经过责任链上各个节点的处理,而Sentinel的限流、熔断就是通过责任链上的这些节点实现的。

要想深入了解原理,还是得从源码上入手,下面直接进入Sentinel的源码阅读。

二、源码阅读

2.1 源码阅读入口及流程总结

读源码先得找到源码入口。我们经常使用@ SentinelResource来标记一个方法,可以将这个被@ SentinelResource标记的方法看成是一个Sentinel资源。因此,我们以@ SentinelResource为入口,找到其切面,看看切面拦截后所做的工作,就可以明确Sentinel的工作原理了。直接看注解@SentinelResource的切面代码(SentinelResourceAspect)。

可以清晰的看到Sentinel的行为方式。进入SentinelResource切面后,会执行SphU.entry方法,在这个方法中会对被拦截方法做限流和熔断的逻辑处理。

如果触发熔断和限流,会抛出BlockException,我们可以指定blockHandler方法来处理BlockException。而对于业务上的异常,我们也可以配置fallback方法来处理被拦截方法调用产生的异常。

所以,Sentinel熔断限流的处理主要是在SphU.entry方法中,其主要处理逻辑见下图源码。

可见,在SphU.entry方法中,Sentinel实现限流、熔断等功能的流程可以总结如下:

  • 获取Sentinel上下文(Context);

  • 获取资源对应的责任链;

  • 生成资源调用凭证(Entry);

  • 执行责任链中各个节点。

2.2  责任链的执行

再来看下面这张图,是不是很清晰了?

图片

NodeSelectorSlot用于获取资源对应的Node,并构建Node调用树,将SentinelSource的调用链路以Node Tree的形式组起来。ClusterBuilderSlot为当前Node创建对应的ClusterNode,聚合相同资源对应的不同Context的Node,后续的限流依据就是这个ClusterNode。

ClusterNode继承自StatisticNode,记录着相应资源处理的一些统计数据。StatisticSlot用于更新资源调用的相关计数,用于后续的限流判断使用。FlowSlot根据资源对应Node的调用计数,判断是否进行限流。

至此,Sentinel的责任链执行逻辑就完整了。

三、原理总结

通过对Sentinel源码的梳理,可以很清晰的理解Sentinel的限流过程,总结如下:

  • 三大组件Context、Entry、Node,是Sentinel的核心组件,各类信息及资源调用情况都由这三大类持有;

  • 采用责任链模式完成Sentinel的信息统计、熔断、限流等操作;

  • 责任链中NodeSelectSlot负责选择当前资源对应的Node,同时构建node调用树;

  • 责任链中ClusterBuilderSlot负责构建当前Node对应的ClusterNode,用于聚合同一资源对应不同Context的Node;

  • 责任链中的StatisticSlot用于统计当前资源的调用情况,更新Node与其对用的ClusterNode的各种统计数据;

  • 责任链中的FlowSlot根据当前Node对应的ClusterNode(默认)的统计信息进行限流;

  • 资源调用统计数据(例如PassQps)使用滑动时间窗口进行统计;

  • 所有工作执行完毕后,执行退出流程,补充一些统计数据,清理Context。

参考文献:github.com/alibaba/Sen…

- END -

希望今天的讲解对大家有所帮助,谢谢!

Thanks for reading!

作者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长。
关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。