分布式速率限流

分布式速率限流:令牌桶/漏桶/固定窗口,Redis 实现,返回是否允许放行

分布式速率限流:传入 key 与规则,返回是否允许放行(allowed)。
基于 Redis 实现,多台服务器共用同一计数,适合小程序、后台 API 防刷。

支持令牌桶(允许突发)、漏桶(平滑输出)、固定窗口(简单配额)。
典型场景:登录防爆破、短信验证码、领券抽奖、评论发帖、导出报表限频。

调用地址:https://api.ynlskj.com.cn/gateway/ratelimit

请求方法:POST

在其他地方怎么调用

  1. 请求地址用上面的调用地址,把 JSON 放在请求体里
  2. 方法用 POST
  3. API Key 只能放在请求头 X-API-Key,不要写进网址,也不要写进 Query 框
  4. Key 在「个人中心 → API Key」里复制,登录后会自动填入你自己的 Key

参数说明

参数位置必填说明
keyBody JSON限流标识,如 login:user_123sms:13812345678export:admin_5
actionBody JSONcheck 判断是否放行并扣减(默认)、peek 只查询不扣减、reset 重置计数
algorithmBody JSONtoken_bucket 令牌桶(默认)、leaky_bucket 漏桶、fixed_window 固定窗口
limitBody JSON时间窗口内允许次数,默认配合 window 使用,如 10 次/60 秒
windowBody JSON时间窗口秒数,默认 60,最大 86400
rateBody JSON令牌桶:每秒补充令牌数。未传时由 limit/window 自动换算
burstBody JSON令牌桶:桶容量(允许突发上限),默认等于 limit
capacityBody JSON漏桶时漏桶容量,默认等于 limit
leak_rateBody JSON漏桶时否漏桶漏出速率(次/秒),默认 limit/window
costBody JSON本次消耗配额,默认 1
namespaceBody JSON命名空间,用于同一账号下隔离不同业务线的 key
X-API-KeyHeader你的 API Key

这个接口是干什么的?

把「防刷、控频、限流」做成远程 API。你的业务在执行敏感操作之前先调本接口,传入一个 key(如用户 ID、IP、手机号),平台用 Redis 分布式计数 判断这次是否放行,返回 allowed: true/false

适合不想自己维护 Redis 限流代码的团队:小程序登录、短信验证码、领券抽奖、评论发帖、后台导出等,都可以远程调一次完成限流判断。

典型使用流程

  1. 业务收到请求(如用户点击「获取验证码」)
  2. 先调本接口key=sms:13812345678,规则 1 小时 3 次
  3. 看返回allowed=true 才继续发短信;false 则提示「操作太频繁,请 retry_after 秒后再试」

适用场景

场景key 示例建议规则
登录防爆破login:ip_1.2.3.4login:user_1231 分钟 5 次,令牌桶
短信验证码sms:138123456781 小时 3 次,固定窗口
领券 / 抽奖coupon:user_88每天 1 次,固定窗口
评论 / 发帖post:user_8810 秒 1 次,漏桶
后台导出报表export:admin_51 小时 3 次,令牌桶
开放 API 防刷api:partner_abc100 次/分钟,令牌桶

三种算法怎么选?

算法特点适合
token_bucket 令牌桶匀速补充令牌,允许一定突发(桶满时可连过几笔)登录、下单、AI 调用等大多数场景(默认推荐
leaky_bucket 漏桶请求进入桶后以固定速率漏出,输出更平滑写库、调用慢接口、希望流量均匀的场景
fixed_window 固定窗口每个时间窗口内固定配额,实现简单「每天 N 次」「每小时 N 次」等硬性配额

请求示例

场景Body 示例
登录限流(默认令牌桶){"key":"login:user_10086","limit":10,"window":60}
短信 1 小时 3 次{"key":"sms:13812345678","limit":3,"window":3600,"algorithm":"fixed_window"}
漏桶平滑限流{"key":"post:user_88","algorithm":"leaky_bucket","capacity":5,"leak_rate":0.2}
只查询不扣减{"action":"peek","key":"login:user_10086","limit":10,"window":60}
管理员重置计数{"action":"reset","key":"login:user_10086","limit":10,"window":60}

业务侧代码示例(伪代码)

resp = POST /gateway/ratelimit {"key":"sms:"+phone,"limit":3,"window":3600}
if (!resp.data.allowed) {
  return "操作太频繁,请" + resp.data.retry_after + "秒后再试"
}
// allowed=true,继续发短信...

说明与限制

  • 基于 Redis 实现,多台业务服务器共用同一计数,保证分布式一致
  • 每个 API Key 账号下的 key 相互隔离;可用 namespace 再分子业务
  • check 每次成功调用扣 1 次平台套餐次数;高频场景建议批量业务合并 key 设计
  • 限流状态存在 Redis,reset 可人工清零;key 长期不用会自动过期释放

返回说明

字段说明
retok 成功,err 失败
data.allowed核心字段:true 表示本次允许放行,false 表示已触发限流
data.remaining剩余可用次数(配额内)
data.retry_after被拒绝时,建议客户端等待的秒数后再重试
data.reset_at配额重置的 Unix 时间戳(固定窗口时有效)
data.key / algorithm本次限流的 key 与算法
data.rate / burst令牌桶参数回显
data.capacity / leak_rate漏桶参数回显
data.limit / window固定窗口参数回显
msg本站提示,如「次数充足,剩余 99 次」或「次数不足,剩余 0 次」
remain_quota本次调用后的剩余次数

可直接复制的代码

未登录时示例只显示「你的密钥」。登录后会自动填入你自己的 Key,不会展示别人的。

<?php
$ch = curl_init('https://api.ynlskj.com.cn/gateway/ratelimit');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => ['X-API-Key: 你的密钥', 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS => '{
    "action": "check",
    "key": "login:user_10086",
    "limit": 10,
    "window": 60,
    "algorithm": "token_bucket"
}',
]);
echo curl_exec($ch);

请求参数演示

{"action":"check","key":"login:user_10086","limit":10,"window":60,"algorithm":"token_bucket"}

响应演示

{"ret":"ok","data":{"action":"check","algorithm":"token_bucket","key":"login:user_10086","allowed":true,"remaining":9,"retry_after":0,"reset_at":0,"rate":0.166667,"burst":10,"cost":1}}

在线调试

登录后可在线调试。调试会真实调用网关并消耗次数。

去登录