lua-resty-limit-traffic 提供动态key、多算法、毫秒级精度的策略性限流,支持按业务维度差异化控制,而原生limit_req仅支持静态IP漏桶限流。

为什么需要 lua-resty-limit-traffic 而不只是原生 limit_req
Nginx 原生 limit_req 基于漏桶,规则静态、键固定(如仅限 IP)、无法按业务维度差异化控制。比如:短信接口该比查询接口更严,登录接口需识别设备指纹而非只看 IP,促销页面要按用户等级放行不同速率——这些都超出原生模块能力。而 lua-resty-limit-traffic 在 OpenResty 环境中提供令牌桶、漏桶、并发数三种限流器,支持动态 key、运行时权重调整、毫秒级精度,是实现策略性限流的工程基础。
核心配置与初始化准备
确保已安装 OpenResty(非普通 Nginx),并在 http 块中完成以下声明:
- 定义共享字典:
lua_shared_dict my_limit_store 10m;(用于缓存限流策略) - 设置 Lua 模块路径:
lua_package_path "/path/to/lua/?.lua;;"; - 预加载初始化脚本:
init_by_lua_file /path/to/limit_init.lua;
其中 limit_init.lua 可从配置文件(如 limit.txt)读取多维度策略,例如:user_vip-50-200(VIP 用户:50r/s,桶容量 200)api_sms-10-30(短信接口:10r/s,桶容量 30)
解析后存入共享字典,供后续请求实时查用。
按请求特征动态选策略
在 location /api 的 access_by_lua_block 中编写逻辑:
- 提取关键标识:优先用
ngx.var.arg_token或ngx.var.http_x_user_id;无则回落到ngx.var.binary_remote_addr - 组合策略键名:如
"api_" .. ngx.var.uri:match("/api/(%w+)")得到api_login,再查共享字典获取对应 rate/burst - 支持运行时加权:对含手机号参数的请求,
weight = ngx.var.arg_phone and 2 or 1,让高风险操作消耗双倍令牌
这样,同一 IP 访问 /api/login 和 /api/profile,会命中不同限流参数;一个带有效 token 的 VIP 用户,也能获得远高于匿名用户的配额。
响应头与降级协同
限流不是单纯拦截,而是传递信号并配合下游动作:
- 成功请求返回标准限流头:
X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset - 被拒绝时返回
429 Too Many Requests,同时写入 Redis 记录该 key 的高频行为,供风控系统后续封禁 - 可联动降级:当
limiter:incoming()返回delay > 1.0(延迟超 1 秒),主动改走缓存托底数据,避免用户卡顿
这种设计把限流从“闸门”变成“交通调度员”,既保核心资源不被打垮,又不让真实用户感知突兀中断。











