Sentinel原理与源码
文章平均质量分 90
Sentinel原理与源码
东阳马生架构
回归初心,保持好奇心,享受那些"成功解题"的喜悦~
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Sentinel源码—9.限流算法的实现对比二
其次通过WarmUpController的coolDownTokens()方法获取最新的令牌数,接着利用CAS来保证更新令牌桶的线程安全性,最后通过减去上一秒通过的QPS数得到目前令牌桶剩余的令牌数来更新。当系统启动时,桶内令牌数最大,令牌生成速率最低,允许的QPS最低。Guava中的预热是通过控制令牌的生成时间来实现的,Sentinel中的预热则是通过控制每秒通过的请求数来实现的。注意:Guava中的预热是通过控制令牌的生成时间来实现的,Sentinel中的预热是通过控制每秒通过的请求数来实现的。原创 2025-04-23 22:10:55 · 1222 阅读 · 0 评论 -
Sentinel源码—9.限流算法的实现对比一
也就是无需等前面的请求完全被处理完,才确定后面的请求被处理的时间。如果在此时(currentTime)通过当前请求,则当前请求的通过时间就比它最早的预期通过时间(expectedTime)要早,即当前请求和最近通过的请求的时间间隔变小了,比最小间隔时间costTime还小,所以此时必然会超QPS阈值。同时,为了避免等待的各个并发线程被同时唤醒,可以利用原子变量的addAndGet()方法 + 假设等待请求已被通过的方式,实现需要等待的并发请求进行睡眠等待的时间都不一样,从而实现并发请求排队等待的效果。原创 2025-04-23 22:09:48 · 1034 阅读 · 0 评论 -
Sentinel源码—8.限流算法和设计模式总结二
在Sentinel中,使用适配器模式将不同框架和库的接口适配为统一的接口,如SphU类。fireEntry()方法相当于AOP在执行完before()方法后调用pjp.proceed()方法,也就是调用责任链上的下一个节点的entry()方法。fireExit()方法相当于AOP在执行完exit()方法后调用pjp.proceed()方法,也就是调用责任链上的下一个节点的exit()方法。entry()方法相当于AOP的before()方法,也就是入口方法,因此责任链执行时会调用entry()方法。原创 2025-04-22 23:52:06 · 1101 阅读 · 0 评论 -
Sentinel源码—8.限流算法和设计模式总结一
延迟计算指的是不需要单独的线程来定时生成令牌或从漏桶中定时取请求,而是由调用限流器的线程自己来计算是否有足够的令牌以及需要sleep的时间。这种算法的一个重要特性是:无论请求的接收速率如何变化,请求的处理速率始终是稳定的,这就确保了系统的负载不会超过预设的阈值。当桶中等待的请求数超过桶的容量后,后续的请求就不再加入桶中。由于以固定的速率处理请求,所以可以有效地平滑和整形流量,避免流量的突发和波动,类似于消息队列的削峰填谷的作用。每来一个请求,请求数加一,如果请求数超过最大限制,就拒绝该请求。原创 2025-04-22 23:51:05 · 1068 阅读 · 0 评论 -
Sentinel源码—7.参数限流和注解的实现二
下面的代码为sayHello()方法添加了@SentinelResource注解,并指定了资源名称为sayHello以及熔断降级时的回调方法fallback()。这样在请求sayHello()方法后,就可以在Sentinel Dashboard上看到此资源,然后就可以针对此资源进行一系列的规则配置了。利用Spring AOP拦截@SentinelResource注解,最后调用SphU.entry()方法来进行处理。原创 2025-04-21 22:50:42 · 438 阅读 · 0 评论 -
Sentinel源码—7.参数限流和注解的实现一
可以设置一个规则,根据用户ID来限制每个用户的查询频率,将限流的维度从资源维度细化到参数维度,从而实现每个用户每10秒只能查询接口1次。比如希望影院工作人员可以每秒查询10次,老板可以每秒查询100次,而购票者则只能每10秒查询一次,其中工作人员的userId值为100和200,老板的userId值为9999,那么可以如下配置:需要注意限流阈值是以秒为单位的,所以需要乘以统计窗口时长10。参数限流允许根据不同的参数条件设置不同的流量控制规则,这种方式非常适合处理特定条件下的请求,因为能更加精细地管理流量。原创 2025-04-21 22:49:52 · 1469 阅读 · 0 评论 -
Sentinel源码—6.熔断降级和数据统计的实现二
调用ArrayMetric的addPass()进行数据统计的逻辑如下:首先通过LeapArray的currentWindow()方法获取当前时间所在的样本窗口,然后调用MetricBucket的addPass()方法统计并存储数据到样本窗口中。如果当前样本窗口的起始时间大于计算出的样本窗口起始时间,则说明计算出的样本窗口已过时,要将原来的样本窗口替换为新样本窗口。滑动窗口不会指定固定的时间窗口起点与终点,而是将处理请求的时间点作为该请求对应时间窗口的终点,起点则是向前距离该终点一个时间窗口长度的时间点。原创 2025-04-20 21:55:14 · 1011 阅读 · 0 评论 -
Sentinel源码—6.熔断降级和数据统计的实现一
比如在执行ExceptionCircuitBreaker的onRequestComplete()方法中,会先统计异常数errorCount和总请求数totalCount,然后根据熔断降级的规则判断是否达到打开或关闭熔断器的阈值,最后执行比如AbstractCircuitBreaker的transformToOpen()方法打开熔断器。但完成对请求的规则验证后,则会调用Entry的exit()方法,而Entry的exit()方法最终就会执行到DegradeSlot的exit()方法。原创 2025-04-20 21:54:01 · 1288 阅读 · 0 评论 -
Sentinel源码—5.FlowSlot借鉴Guava的限流算法二
结合如下的图(令牌的发放时间间隔随着已存储的令牌不同而不同)可知:maxPermits - thresholdPermits就是梯形的高,stableIntervalMicros + coldIntervalMicros就是梯形的两个底的和。该等待时间又会分为两部分进行计算:第一部分是获取预热阶段的令牌的耗时,第二部分是获取稳定阶段的令牌的耗时。SmoothBursty应对突发流量是有前提条件的,只有在令牌桶内有存储的令牌情况下,才会放行相应的突发流量,而令牌桶内的已存储令牌是低流量时省下来的。原创 2025-04-19 22:14:36 · 1065 阅读 · 0 评论 -
Sentinel源码—5.FlowSlot借鉴Guava的限流算法一
如果下一个请求的预期到达时间实际上已经过去了,并且假设下次请求期望到达的时间点是past,现在的时间点是now。在RateLimiter处于长时间未被使用的状态下:如果是利用不足导致的,那么应该让存储的令牌比新鲜的令牌发放得更快。延迟计算指的是不需要单独的线程来定时生成令牌或者从漏桶中定时获取请求,而是由调用限流器的线程自己计算是否有足够的令牌以及需要sleep的时间。接下来假设这个函数是一条水平线:如果其高度恰好为1/QPS,则函数的效果不存在,因为此时表示以与新鲜的令牌完全相同的成本提供存储的令牌。原创 2025-04-19 22:12:30 · 888 阅读 · 0 评论 -
Sentinel源码—4.FlowSlot实现流控的原理二
如果在此时(currentTime)通过当前请求,则当前请求的通过时间就比它最早的预期通过时间(expectedTime)要早,即当前请求和最近通过的请求的时间间隔变小了,比最小间隔时间costTime还小,所以此时必然会超QPS阈值。WarmUpController的核心原理是:首先根据当前时间和上一个时间窗口通过的QPS同步令牌桶内的令牌数,然后比较桶内令牌数和告警值来计算当前时间窗口允许通过的告警QPS,最后比较当前请求下的QPS是否大于允许通过的告警QPS来决定限流。原创 2025-04-17 23:02:43 · 1680 阅读 · 0 评论 -
Sentinel源码—4.FlowSlot实现流控的原理一
当FlowSlot的entry()方法对请求进行流控规则验证时,会调用规则检查器FlowRuleChecker的checkFlow()方法进行检查,最终会通过FlowRule的getRater()方法获取流控规则对应的流量整形控制器,然后调用TrafficShapingController的canPass()方法对请求进行检查。也就是testOrder被流控的时机就是当testPay的QPS达到3的时候,3并不是testOrder所访问的次数,而是testPay这个接口被访问的次数。原创 2025-04-17 23:01:24 · 1104 阅读 · 0 评论 -
Sentinel源码—3.ProcessorSlot的执行过程二
当AuthorityDemo调用AuthorityRuleManager的loadRules()方法加载规则时,便会执行DynamicSentinelProperty的updateValue()方法,也就是会触发执行LISTENER的configUpdate()方法加载权限规则到一个map中,即执行RulePropertyListener的loadAuthorityConf()方法加载规则,从而完成黑白名单权限控制规则的加载和初始化。当配置发生变化时,就可以遍历监听器集合然后调用回调方法进行处理。原创 2025-04-16 23:22:12 · 1251 阅读 · 0 评论 -
Sentinel源码—3.ProcessorSlot的执行过程一
由于ClusterNode会统计某个资源在全部Context下的调用数据,它是按照集群中的资源维度进行调用数据统计的,而StatisticSlot的entry()调用DefaultNode的方法统计单机下的资源时,会顺便调用ClusterNode的方法来统计集群下的资源调用,所以通过ClusterNode就可以获取集群中某个资源的调用数据。每当一个线程处理包含某些资源的接口请求时,会调用SphU的entry()方法去创建并管控该接口中涉及的Entry资源访问对象。原创 2025-04-16 23:21:05 · 1035 阅读 · 0 评论 -
Sentinel源码—2.Context和处理链的初始化二
需要注意:即便是多个线程访问同样的资源(ResourceWrapper对象的属性一样),多个线程也会对应多个Entry对象(Entry对象之间的基本属性一样),多个线程也会对应多个Context对象(使用ThreadLocal存放Context对象),从而多个Entry对象会对应各自的Context对象。SpiLoader的load()方法在读取SPI文件时,会按order属性对Slot进行排序,并将排好序的ProcessorSlot实现类放入sortedClassList中。原创 2025-04-15 21:38:49 · 1355 阅读 · 0 评论 -
Sentinel源码—2.Context和处理链的初始化一
如果获取到的Context为空,也就是当前线程没有绑定Context,那么就调用InternalContextUtil的internalEnter()方法创建一个Context对象,也就是调用ContextUtil的trueEnter()方法创建一个Context对象,并把这个Context对象放入ThreadLocal线程变量contextHolder中。在处理一个请求对应的一个资源时或者多个资源时,这些资源的操作必须要建立在一个Context环境下,而且每一个资源的操作必须要通过Entry对象来完成。原创 2025-04-15 21:37:50 · 842 阅读 · 0 评论 -
Sentinel源码—1.使用演示和简介二
系统规则是针对整个系统进行流量控制的,是操作系统级别或服务器级别的,不是应用级别或资源级别的。下面的配置要达到的效果是:当资源testSlowCall在10秒(统计时长)内请求数达10个(最小请求数)以上,且响应时长超过1秒(最大RT)的请求数量大于1(10 * 0.1)个时进行熔断,熔断5秒后资源testSlowCall会变成Half Open状态。这个接口的熔断规则如下:当10秒(统计时长)内达到10个请求(最小请求数)以上,而且请求异常比例超过20%时,就会触发熔断并熔断时长为5秒。原创 2025-04-14 23:38:00 · 1038 阅读 · 0 评论 -
Sentinel源码—1.使用演示和简介一
如果队列中的请求超过一定数量或者等待时间超过一定阈值,则直接拒绝新的请求,从而避免服务器的过载。接着,在Dashboard上建立一个资源名为testQps的流控规则,也就是针对testQps这个资源建立一个QPS为1的流控配置。也就是如果超出了配置的阈值,则会等待1秒钟,而不是直接拒绝,从而尽可能保证不丢失用户的请求。也就是testOrder被流控的时机就是当testPay的QPS达到3的时候,3并不是testOrder所访问的次数,而是testPay接口被访问的次数。原创 2025-04-14 23:31:23 · 1218 阅读 · 0 评论
分享