漏桶强制匀速放行,令牌桶允许短时爆发;漏桶适合消息推送等强顺序场景,令牌桶适合api网关等需兼顾体验的路径,laravel 10+ ratelimiter默认采用令牌桶模型。

在Laravel项目中实现精准、可伸缩的接口限流,必须理解底层算法如何影响突发流量容忍度与系统资源利用率——漏桶强制匀速放行,令牌桶允许短时爆发但需严控桶容量。
漏桶算法:恒定速率削峰填谷
方法一:基于时间差动态排水
1. 初始化漏桶时设定容量(如5)和每秒排水量(如1),同时记录首次调用时间戳;
2. 每次请求到来,先计算自上次调用至今的流逝秒数,按rate × elapsed_time扣减当前水量;
3. 若新请求体积(amount)与当前剩余水量之和未超容量,则加水并放行,否则拒绝;
这一步必须用synchronized或Redis锁保障water变量原子性,【并发下未加锁会导致水量误判,瞬间突破限流阈值】。
方法二:预分配固定窗口队列
将请求排队存入内存队列或Redis List,后台协程以恒定间隔pop并执行;队列满则直接丢弃新请求。
令牌桶算法:弹性应对突发流量
第一步:初始化桶参数
设定桶容量(burst)、令牌生成速率(r tokens/sec)及初始令牌数(通常等于容量);
第二步:请求时动态补发令牌
根据当前时间与上次更新时间差,计算应新增令牌数 = r × (now − last_time),再取min(容量, 当前令牌 + 新增量);
第三步:尝试消耗令牌
若当前令牌 ≥ 请求所需数量(通常为1),则扣减并返回true;否则返回false触发限流响应。
注意:Laravel 10+ 的RateLimiter门面默认使用此模型,但【桶容量必须小于等于系统单秒最大处理能力,否则积压令牌会在下一秒引发雪崩】。
两种算法在Laravel中的落地差异
漏桶适合消息推送、邮件发送等强顺序、低延迟敏感型任务——它把请求“存下来慢慢喂”,天然适配队列驱动场景;
令牌桶更适合API网关、登录接口等需要兼顾稳定性与用户体验的路径——用户连续点击两次提交,第一次耗尽令牌后第二次仍可能因桶内余量而通过;
在Laravel Swoole环境下,漏桶需配合协程定时器维持排水节奏,令牌桶则可依赖Redis INCR + EXPIRE组合模拟时间滑动窗口。











