Skip to content

接口限流

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防刷短信

相关资源

基于 MIT 许可发布