接口限流
youlai-think 当前未集成限流功能。如有需求,推荐以下方案:
推荐方案
方案一:中间件实现
php
<?php
namespace app\middleware;
use Closure;
use think\Request;
use think\Response;
use think\facade\Cache;
class RateLimitMiddleware
{
protected int $limit = 10; // 每秒最大请求数
protected int $window = 1; // 时间窗口(秒)
public function handle(Request $request, Closure $next): Response
{
$ip = $request->ip();
$key = "rate_limit:{$ip}";
$count = Cache::inc($key);
if ($count === 1) {
Cache::expire($key, $this->window);
}
if ($count > $this->limit) {
return json([
'code' => 'A0502',
'msg' => '请求过于频繁,请稍后再试',
'data' => null
]);
}
return $next($request);
}
}注册中间件:
php
// app/middleware.php
return [
\app\middleware\RateLimitMiddleware::class,
];方案二:Redis + 令牌桶
php
<?php
namespace app\middleware;
use Closure;
use think\Request;
use think\Response;
use think\facade\Cache;
class TokenBucketMiddleware
{
protected int $rate = 10; // 每秒生成令牌数
protected int $capacity = 20; // 桶容量
public function handle(Request $request, Closure $next): Response
{
$ip = $request->ip();
$key = "token_bucket:{$ip}";
$tokens = Cache::get($key, $this->capacity);
if ($tokens < 1) {
return json([
'code' => 'A0502',
'msg' => '请求过于频繁',
'data' => null
]);
}
Cache::set($key, $tokens - 1, 1);
return $next($request);
}
}方案三:Nginx 限流
在反向代理层实现限流:
nginx
# 定义限流区域
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://localhost:8000;
}
}应用场景
| 场景 | 建议配置 | 说明 |
|---|---|---|
| 普通接口 | 10/s | 默认配置 |
| 登录接口 | 2/s | 防暴力破解 |
| 短信验证码 | 1/s | 防刷短信 |
