目录一、限流到底在管什么(一)整点那一秒发生了什么(二)速率、并发与排队:三种约束各管一段1、速率限制:单位时间放进来多少2、并发限制:此刻同时在办多少3、排队限制:最多允许等多少(三)否决式与整形式:被限住的请求去哪儿(四)读懂限流参数的三把尺子(五)实验环境与运行方式二、固定窗口:最便宜的计数器与它的边界漏洞(一)算法与实现(二)边界双倍突发的推演(三)它仍然值得用的场合三、滑动窗口:把格子切细,还是把账记全(一)滑动日志:精确但状态随流量增长(二)分桶滑动计数:用子窗口换内存(三)两桶加权近似:只存两个数(四)实测:子桶越多,双倍突发并没有消失(五)旁支:TCP 的滑动窗口管的是另一件事四、漏桶:把不规则的进水整成匀速出水(一)漏桶的两种形态1、队列式漏桶2、计量式漏桶(二)队列式漏桶的代价:排队不是免费的(三)Nginx limit_req:一只用 excess 记账的漏桶1、配置语义2、千分位记账的 excess3、延迟交给定时器,而不是让 worker 睡觉4、burst 是排队容量,不是免费额度五、令牌桶:允许攒令牌的限流(一)定义与两个参数(二)懒惰补充:不需要后台线程(三)令牌桶与漏桶:一体两面(四)四类算法横向对照六、主流限流组件的取舍(一)Guava RateLimiter:单机平滑令牌桶(二)Resilience4j RateLimiter:按周期发放的许可(三)Sentinel:滑动窗口统计与三种流控效果(四)集群配额:把令牌发放收归一处(五)其他常见选择(六)选型对照七、Guava RateLimiter 的用法与语义(一)两种构造与四个入口(二)预消费:这一笔的账,记在下一位头上(三)tryAcquire 的判定口径(四)setRate:存量按比例换算八、源码精读:SmoothRateLimiter 的时间账本(一)类结构与四个字段(二)resync:有人来,才补账(三)reserveEarliestAvailable:先放行,后结算(四)SmoothBursty:存量零成本(五)SmoothWarmingUp:把存量翻译成等待时间1、预热函数与三个关键量2、积分的计算3、冷却速度4、实测爬坡曲线(六)锁与睡眠:为什么 sleep 在锁外九、复刻与对账:一只迷你平滑限流器(一)为什么要自己复刻(二)逐笔对账的方法十、生产落地:从单机限速到分层防护(一)六个常见误用1、每次请求 new 一个 RateLimiter2、在 IO 线程或入口线程里 acquire3、acquire 一个很大的数4、单机阈值乘以实例数5、只限次数,不看成本6、不监控等待与拒绝(二)集群里的误杀与放大(三)分层防护:四道关各守一段(四)被限住之后:响应契约与客户端行为(五)参数从哪里来十一、总结(一)四个追问的答案(二)适用范围与不适用场景参考文章干货分享,感谢您的阅读!“每秒最多 100 次”真正落到系统里至少牵出四个追问:这 100 次按哪一秒算?第 101 次是立刻拒绝还是排队等?空闲了一会儿之后能不能一口气多放几个?部署了 8 个实例之后,“100”说的是每台还是总共?很多线上事故并不是因为没有限流,而是因为限流器在这几个问题上的回答,和写配置的人心里想的不一样。这次我们要解决的问题是:把限流这件事从“背四个算法名字”推进到“能算清每一笔账”——给定一个限流配置,能准确说出它在边界、突发、空闲和多实例下到底会放行多少、拒绝多少、让谁等多久。我们先厘清限流到底在约束什么,再把固定窗口、滑动窗口、漏桶、令牌桶四类算法放进同一个可复现的虚拟时间实验台,用实测数字去看它们在窗口边界、突发流量、对抗流量下的真实表现;顺路拆开 Nginxlimit_req的千分位记账和 TCP 滑动窗口这两个常被混为一谈的“近亲”。随后横向对照 Guava、Resilience4j、Sentinel、集群配额等主流组件;最后把重心放在 GuavaRateLimiter上——它的预消费语义、懒惰补账、预热积分都藏在不到四百行的SmoothRateLimiter里,我们会逐行读懂,再自己复刻一只迷你版本,与 Guava 在同一条虚拟时间线上做七万次逐笔对账。本文适合在 Java 服务里配置或自研限流的后端工程师,以及需要为网关、Nginx 定阈值的同学。读完希望你应当能够:判断某个场景该用否决式还是整形式、该选哪类算法;看懂burst、nodelay