流控三板斧——Sentinel滑动窗口、令牌桶与Dubbo负载均衡
流控三板斧 前三篇讲了一个核心矛盾:分布式系统里——网络和时钟不可靠——所以你必须在一致性和可用性之间做取舍——Raft 用 majority 保证 CP——Nacos Distro 用最终一致性取 AP。 但取舍不只发生在数据一致性层面——流量控制层面同样存在。每个服务有自己的承载上限——超过上限就必须拒绝一部分请求——这就是限流。拒绝哪些请求?以什么粒度计数?桶还是窗口? 📌 前置知识:需要有 Sentinel 基本概念(知道它是限流熔断组件)和 Dubbo 基本用法(知道 @DubboReference 怎么调用远程服务)。如果还没用过 Sentinel 的 Dashboard——建议先对着官方文档跑一遍 Quick Start——不需要深入——但得知道控制台里"流控规则"长什么样。 一、为什么"每秒 100 个请求"这种限流方式有 Bug——固定窗口的边界突刺 对限流最直观的理解:系统处理能力是每秒 100 个——超过就拒绝。实现这个最简单的办法——搞一个计数器——每秒归零。 // 固定窗口计数器——最朴素的想法 class FixedWindowRateLimiter { private long windowStart = System.currentTimeMillis(); private int counter = 0; private final int limit = 100; public synchronized boolean tryAcquire() { long now = System.currentTimeMillis(); if (now - windowStart > 1000) { windowStart = now; // 新窗口——计数器归零 counter = 0; } if (counter < limit) { counter++; return true; // 放行 } return false; // 限流 } } 看起来没毛病——每秒最多通过 100 个——超过就拒绝。问题出在窗口边界: ...