分布式速率限流
分布式速率限流:令牌桶/漏桶/固定窗口,Redis 实现,返回是否允许放行
分布式速率限流:传入 key 与规则,返回是否允许放行(allowed)。
基于 Redis 实现,多台服务器共用同一计数,适合小程序、后台 API 防刷。
支持令牌桶(允许突发)、漏桶(平滑输出)、固定窗口(简单配额)。
典型场景:登录防爆破、短信验证码、领券抽奖、评论发帖、导出报表限频。
基于 Redis 实现,多台服务器共用同一计数,适合小程序、后台 API 防刷。
支持令牌桶(允许突发)、漏桶(平滑输出)、固定窗口(简单配额)。
典型场景:登录防爆破、短信验证码、领券抽奖、评论发帖、导出报表限频。
调用地址:https://api.ynlskj.com.cn/gateway/ratelimit
请求方法:POST
在其他地方怎么调用
- 请求地址用上面的调用地址,把 JSON 放在请求体里
- 方法用
POST - API Key 只能放在请求头
X-API-Key,不要写进网址,也不要写进 Query 框 - Key 在「个人中心 → API Key」里复制,登录后会自动填入你自己的 Key
参数说明
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
key | Body JSON | 是 | 限流标识,如 login:user_123、sms:13812345678、export:admin_5 |
action | Body JSON | 否 | check 判断是否放行并扣减(默认)、peek 只查询不扣减、reset 重置计数 |
algorithm | Body JSON | 否 | token_bucket 令牌桶(默认)、leaky_bucket 漏桶、fixed_window 固定窗口 |
limit | Body JSON | 否 | 时间窗口内允许次数,默认配合 window 使用,如 10 次/60 秒 |
window | Body JSON | 否 | 时间窗口秒数,默认 60,最大 86400 |
rate | Body JSON | 否 | 令牌桶:每秒补充令牌数。未传时由 limit/window 自动换算 |
burst | Body JSON | 否 | 令牌桶:桶容量(允许突发上限),默认等于 limit |
capacity | Body JSON | 漏桶时 | 漏桶容量,默认等于 limit |
leak_rate | Body JSON | 漏桶时否 | 漏桶漏出速率(次/秒),默认 limit/window |
cost | Body JSON | 否 | 本次消耗配额,默认 1 |
namespace | Body JSON | 否 | 命名空间,用于同一账号下隔离不同业务线的 key |
X-API-Key | Header | 是 | 你的 API Key |
这个接口是干什么的?
把「防刷、控频、限流」做成远程 API。你的业务在执行敏感操作之前先调本接口,传入一个 key(如用户 ID、IP、手机号),平台用 Redis 分布式计数 判断这次是否放行,返回 allowed: true/false。
适合不想自己维护 Redis 限流代码的团队:小程序登录、短信验证码、领券抽奖、评论发帖、后台导出等,都可以远程调一次完成限流判断。
典型使用流程
- 业务收到请求(如用户点击「获取验证码」)
- 先调本接口:
key=sms:13812345678,规则 1 小时 3 次 - 看返回:
allowed=true才继续发短信;false则提示「操作太频繁,请retry_after秒后再试」
适用场景
| 场景 | key 示例 | 建议规则 |
|---|---|---|
| 登录防爆破 | login:ip_1.2.3.4 或 login:user_123 | 1 分钟 5 次,令牌桶 |
| 短信验证码 | sms:13812345678 | 1 小时 3 次,固定窗口 |
| 领券 / 抽奖 | coupon:user_88 | 每天 1 次,固定窗口 |
| 评论 / 发帖 | post:user_88 | 10 秒 1 次,漏桶 |
| 后台导出报表 | export:admin_5 | 1 小时 3 次,令牌桶 |
| 开放 API 防刷 | api:partner_abc | 100 次/分钟,令牌桶 |
三种算法怎么选?
| 算法 | 特点 | 适合 |
|---|---|---|
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 长期不用会自动过期释放
返回说明
| 字段 | 说明 |
|---|---|
ret | ok 成功,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}}