需在dify中通过本地redis 7.2+实现毫秒级滑动窗口qps限流:启用aof与volatile-lru策略,配置非零db(如/1),使用lua脚本依赖zset和zremrangebyscore原子操作。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

你需要在Dify服务中为多个API Key实现毫秒级精度的QPS控制,避免单账号突发请求压垮后端模型服务,同时不依赖云Redis降低运维成本。
准备本地Redis环境
下载并启动 Redis 7.2+ 版本,确保启用 AOF 持久化与 maxmemory-policy=volatile-lru。这一步不可跳过,【滑动窗口限流必须依赖Redis的ZSET有序集合和原子性ZREMRANGEBYSCORE命令】,低版本Redis不支持Lua脚本中对ZSET的精确时间范围清理。
执行 redis-server /etc/redis.conf 启动服务,确认 6379 端口监听正常。
配置Dify使用本地Redis做限流存储
编辑 Dify 的 .env 文件,在末尾追加:
REDIS_URL=redis://127.0.0.1:6379/1
RATE_LIMITING_ENABLED=true
RATE_LIMITING_REDIS_KEY_PREFIX=dify:rl:
注意:数据库编号必须设为非0(如 /1),避免与会话缓存冲突;【若仍用 db 0,限流计数与 session 数据将互相覆盖导致计数失准】。
编写滑动窗口限流Lua脚本
在 Dify 项目根目录新建 scripts/rate_limit_sliding.lua,内容如下:
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window_ms = tonumber(ARGV[2])
local now_ms = tonumber(ARGV[3])
redis.call('ZREMRANGEBYSCORE', key, 0, now_ms - window_ms)
local current = redis.call('ZCARD', key)
if current
redis.call('ZADD', key, now_ms, now_ms .. ':' .. math.random(1000,9999))
redis.call('PEXPIRE', key, window_ms + 1000)
return 1
else
return 0
end
在API网关层注入限流逻辑
打开 apps/api/routers/api.py,定位到 @router.post("/chat-messages") 装饰器上方,插入以下中间件调用:
① 在文件顶部导入:from core.rate_limit import check_sliding_window
② 在路由函数参数中添加依赖:current_user: CurrentUser = Depends(get_current_user)
③ 在函数体第一行加入:check_sliding_window(current_user.api_key, 30, 1000) # 30 QPS / 1s窗口
这一步操作起来很简单,直接把检查语句贴进去就行。但要注意:每个账号的限流阈值必须从用户角色动态读取,不能硬编码;免费用户走 10 QPS,企业用户走 100 QPS,需查 user.role 字段后传入第二参数。
验证多账号隔离效果
方法一:用 curl 并发触发两个不同 API Key 的请求:
for i in {1..40}; do curl -X POST http://localhost:5001/api/chat-messages -H "Authorization: Bearer key_free_abc" -d '{"inputs":{}}' & done
同时运行:
for i in {1..40}; do curl -X POST http://localhost:5001/api/chat-messages -H "Authorization: Bearer key_ent_xyz" -d '{"inputs":{}}' & done
观察响应状态码:key_free_abc 应在第11次后开始返回 429,而 key_ent_xyz 全部 40 次均成功。
方法二:直连Redis检查ZSET成员数量:
redis-cli -n 1 ZCARD "dify:rl:key_free_abc"
redis-cli -n 1 ZCARD "dify:rl:key_ent_xyz"
两者的计数值应长期稳定在各自阈值附近,且互不影响。











