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 就等于掌握了它的"数据源头"。

相关推荐
weixin199701080161 天前
《淘宝双11同款:基于 Sentinel 的微服务流量防卫兵实战》
微服务·架构·sentinel
一叶飘零_sweeeet2 天前
高可用架构核心:限流熔断降级全解,Sentinel 与 Resilience4j 原理 + 落地实战
架构·sentinel
Fang fan5 天前
Redis基础数据结构
数据结构·数据库·redis·缓存·bootstrap·sentinel
回到原点的码农6 天前
SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
spring cloud·gateway·sentinel
没有bug.的程序员7 天前
黑客僵尸网络的降维打击:Spring Cloud Gateway 自定义限流剿杀 Sentinel 内存黑洞
java·网络·spring·gateway·sentinel
xiaolingting9 天前
Gateway 网关流控与限流架构指南
spring cloud·架构·gateway·sentinel
sc_爬坑之路10 天前
redis windows环境配置读写分离:一主一从 + Sentinel 完整实战
windows·redis·sentinel
sc_爬坑之路10 天前
Linux 部署 Redis:一主一从 + Sentinel 完整实战
linux·redis·sentinel
杜子不疼.10 天前
Spring Cloud 熔断降级详解:用 “保险丝“ 类比,Sentinel 实战教程
人工智能·spring·spring cloud·sentinel
yc_xym12 天前
Redis哨兵(Sentinel)机制
数据库·redis·sentinel