应选用 tinywan/limit-traffic 而非 webman/rate-limiter,因其采用 lua 原子脚本杜绝并发超限、自动注入标准限流头、默认令牌桶语义,且需正确挂载中间件、透传真实 ip 并理解 burst/rate 参数约束。

Webman 里该用 tinywan/limit-traffic 而不是 webman/rate-limiter
面对每秒数百上千的请求洪峰,webman/rate-limiter 的默认 Redis 实现存在并发超限风险:旧版本用 INCR + EXPIRE 两步操作,中间可能被并发请求“插队”,导致多放行 1–2 次。暴力爆破场景下,这就等于开了后门。tinywan/limit-traffic 直接用 Lua 脚本封装原子操作,从根源上堵住竞态漏洞。它还自动注入 X-Rate-Limit-Limit、X-Rate-Limit-Remaining 等标准头,前端能据此做退避重试;而 webman/rate-limiter 需手动调用 $response->withHeader(),漏写就等于没防护。
中间件挂载位置决定限流是否生效
限流中间件挂错地方,等于白配。常见踩坑点:
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 把
Tinywan\LimitTraffic\Middleware\LimitTrafficMiddleware::class写在config/middleware.php的''键下,结果连/static/js/app.js这类静态资源也被计数——攻击者刷 CSS/JS 路径就能提前耗尽额度 - 用
Route::group('/api', function () { })定义路由,但没显式调用->middleware([]),中间件根本不会进组内路由(Webman ≥ 1.0.12 才支持 group 继承,旧版本必须逐个绑定) - 反向代理(如 Nginx)没透传真实 IP,
X-Real-IP或X-Forwarded-For缺失,所有请求都按127.0.0.1统计,全站用户共享一个限流桶
[burst, rate] 参数的真实含义和约束力
[100, 600] 表示“600 秒内最多 100 次”,但这只是配置目标,实际守得住多少,取决于底层驱动和算法实现:
- Redis 驱动下,
tinywan/limit-traffic的 Lua 脚本能严格守住这个上限,误差为 0 -
webman/rate-limiter在高并发压测下,实测可能突破 5–10%,尤其当 TTL 刷新不及时时 - 若改用
apcu驱动,限流只在单进程内生效,多 worker 场景下各算各的,总容量 = 单进程限额 × worker 数,容易误判
令牌桶行为与固定窗口的本质区别
令牌桶允许突发流量,固定窗口不行。比如配置 [100, 60](每分钟 100 次),真实场景中:
- 用户前 5 秒集中发起 100 次请求 → 令牌桶允许(桶初始满,令牌可预支)→ 后续 55 秒拒绝
- 固定窗口算法会在第 60 秒整点清零,第 61 秒又允许 100 次 → 攻击者卡时间点就能绕过
-
tinywan/limit-traffic默认就是令牌桶语义,无需额外配置;而webman/rate-limiter的注解限流底层仍是固定窗口,想模拟令牌桶得自己加延迟逻辑
acquire() 方法,而是让令牌发放速率、桶容量、Redis 原子性、IP 识别链路、中间件作用域全部对齐——漏掉任意一环,限流就变成装饰品。










