Sentinel核心统计节点:滑动窗口与指标计算

SentinelStatisticNode 类的实现,它是所有统计节点(如 DefaultNodeClusterNode)的基类 ,负责 实时采集和管理资源的运行时指标(metrics)

它的核心思想是:

用滑动窗口(Sliding Window)机制,在秒级和分钟级两个时间维度上,高效、准确地统计 QPS、RT、线程数等关键指标。

下面我们从 设计目标、核心结构、滑动窗口原理、指标计算逻辑、线程安全 等角度深入解析。


一、核心目标:统计什么?

StatisticNode 负责维护三类实时指标:

指标类型 存储方式 用途
秒级指标 rollingCounterInSecond(默认 1 秒分 2 个桶 → 每桶 500ms) 实时流控、熔断决策(响应快)
分钟级指标 rollingCounterInMinute(60 个桶,每桶 1 秒) 监控展示、历史回溯、慢速规则
当前线程数 curThreadNumLongAdder 并发控制(如系统保护规则)

✅ 所有指标都基于 滑动窗口(Sliding Window) 实现,底层由 ArrayMetric + LeapArray 支撑。


二、滑动窗口原理(关键!)

Sentinel 的滑动窗口不是"固定窗口"(如 0-1s, 1-2s),而是连续、重叠、滚动的窗口,能更平滑地反映流量变化。

📌 以秒级窗口为例(默认配置):

  • 总窗口长度:1000ms(1秒)

  • 桶数量(sampleCount):2

  • 每个桶长度:500ms

    时间轴: ... |-----500ms-----|-----500ms-----| → 当前窗口 [t-1000, t)

    当前时间 t

  • 每次请求进来,会找到对应的时间桶(bucket),累加指标(pass、block、rt 等)。

  • 超过 1000ms 的旧桶会被自动丢弃(逻辑上"滑出"窗口)。

✅ 优势:

  • 避免固定窗口的"边界突刺"问题(如 0.9s 到 1.1s 瞬间 QPS 翻倍)
  • 实时性高,适合做毫秒级流控

三、关键字段详解

java 复制代码
// 秒级滑动窗口(默认:2个桶,总长1000ms)
private transient volatile Metric rollingCounterInSecond = 
    new ArrayMetric(SampleCountProperty.SAMPLE_COUNT, IntervalProperty.INTERVAL);

// 分钟级滑动窗口(60个桶,每桶1秒,总长60秒)
private transient Metric rollingCounterInMinute = 
    new ArrayMetric(60, 60 * 1000, false);

// 当前线程并发数(使用 LongAdder 高性能计数)
private LongAdder curThreadNum = new LongAdder();

💡 transient 表示不参与序列化(这些是运行时状态,无需持久化)


四、指标如何计算?------ 以 QPS 为例

1. passQps()(秒级通过 QPS)

java 复制代码
return rollingCounterInSecond.pass() / rollingCounterInSecond.getWindowIntervalInSec();
  • pass():返回当前滑动窗口内所有有效桶的 总通过请求数
  • getWindowIntervalInSec():窗口总时长(单位:秒),如 1.0
  • 结果 = 总通过数 / 1秒 → 即 QPS

2. avgRt()(平均响应时间)

java 复制代码
long successCount = rollingCounterInSecond.success();
if (successCount == 0) return 0;
return rollingCounterInSecond.rt() / successCount;
  • rt():窗口内所有成功请求的 总响应时间(毫秒)
  • 除以成功次数 → 平均 RT

3. totalRequest()(最近1分钟总请求数)

java 复制代码
return rollingCounterInMinute.pass() + rollingCounterInMinute.block();
  • 使用 分钟级窗口,用于监控大盘数据

🔁 所有写操作(如 addPassRequest)都会同时更新 秒级 + 分钟级 两个窗口!


五、线程安全设计

  • 滑动窗口(ArrayMetric/LeapArray):内部使用 CAS + 时间戳校验,保证多线程写入安全。
  • curThreadNum :使用 LongAdder(比 AtomicLong 更高性能的并发计数器)。
  • childList 更新(在 DefaultNode 中) :采用 不可变集合替换(copy-on-write) 策略,避免锁竞争。

六、高级功能:预占(Warm Up / 匀速排队)

tryOccupyNext(...) 方法支持 "匀速排队"或"预占令牌" 场景:

  • 当 QPS 超过阈值时,不直接拒绝,而是看 未来某个时间窗口是否能容纳
  • 如果可以,返回需要等待的时间(ms),让请求 sleep 后再执行。
  • 这是 Sentinel Rate Limiter 模式 的核心实现。

⚠️ 此功能常用于削峰填谷,避免突发流量打垮系统。


七、与整体架构的关系

SphU.entry("res") ↓ Context ↓ NodeSelectorSlot ↓ DefaultNode (extends StatisticNode) ↓ ClusterNode (extends StatisticNode) ↘ ↗ FlowSlot / DegradeSlot ↑ | 读取 QPS/RT/thread | DefaultNode
  • DefaultNodeClusterNode 都继承 StatisticNode,共享同一套统计逻辑。
  • 流控规则(FlowRule)在 FlowSlot 中执行时,会调用 node.passQps() 获取当前 QPS。

八、总结:一句话理解 StatisticNode

StatisticNode 是 Sentinel 的"指标心脏",它通过双时间尺度(秒/分)的滑动窗口,高效、准确、线程安全地采集资源的实时运行数据,为流控、熔断、系统保护等能力提供决策依据。

🧠 记住三个关键词:

  1. 滑动窗口(Sliding Window) → 平滑、实时
  2. 双时间尺度(Second + Minute) → 快速响应 + 历史回溯
  3. 指标同步更新(Local + Global) → 支持入口隔离与全局聚合

如果你在调试 Sentinel 或自定义规则,理解 StatisticNode 就等于掌握了它的"数据源头"。

相关推荐
lang201509289 小时前
深入解析Sentinel核心类StatisticSlot
sentinel
lang2015092810 小时前
Sentinel核心机制:Context与EntranceNode解析
网络·sentinel
lang2015092813 小时前
Alibaba Sentinel核心类CtSph深入分析
sentinel
lang2015092817 小时前
Sentinel核心:ClusterNode全局资源统计解析
网络·python·sentinel
没有腰的嘟嘟嘟17 小时前
《Sentinel 限流三板斧:QPS、线程数、热点参数实战解析》
sentinel
兄台の请冷静17 小时前
linux 安装sentinel 并加入systemctl
linux·运维·sentinel
lang201509281 天前
深入解析Sentinel FlowSlot限流机制
sentinel
lang201509281 天前
Sentinel核心接口解析:Sph与SphResourceTypeSupport
sentinel
lang201509281 天前
Sentinel流控规则动态配置解析
服务器·网络·sentinel