You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中用RateLimiter实现API每分钟25次请求限流的方法咨询

用Laravel自带RateLimiter轻松实现API限流

嘿,作为Laravel新手,你选对工具啦!Illuminate\Cache\RateLimiter就是专门解决这类限流问题的,完全不用自己写复杂的循环计数逻辑。我给你捋清楚具体怎么实现,刚好匹配你现有的代码结构:

方案1:直接用RateLimiter的wait方法(最简洁)

首先在控制器顶部引入RateLimiter门面:

use Illuminate\Support\Facades\RateLimiter;

然后改造你的sendRequest方法,让它自动等待直到可以发送请求:

protected function sendRequest()
{
    // 核心逻辑:等待直到请求名额可用(每分钟最多25次)
    // 第一个参数是限流标识key,用来区分不同的限流规则;第二个是每分钟允许的请求次数
    RateLimiter::wait('external-api-requests', 25);

    // 到这里就说明可以发送请求了,执行你的API调用逻辑
    // 比如:
    // $response = Http::get('https://你的目标API地址');
    // return $response;
}

这个wait方法已经帮你做了所有脏活:

  • 用缓存记录请求次数,60秒后自动重置计数
  • 如果当前已经达到25次请求,它会自动等待到下一次有可用名额的时候
  • 完全不用你手动写循环检查!

方案2:保留你的allowRequest结构(更灵活)

如果你想保留自己的allowRequest方法结构,也可以这样实现:

use Illuminate\Support\Facades\RateLimiter;

protected function sendRequest()
{
    if ($this->allowRequest()) {
        // 执行API调用逻辑
    }
}

protected function allowRequest()
{
    // 定义限流规则:key标识、每分钟最多25次、60秒后重置计数
    $limiterKey = 'external-api-requests';
    $maxAttempts = 25;
    $decaySeconds = 60;

    // 检查是否已经达到请求上限
    if (RateLimiter::tooManyAttempts($limiterKey, $maxAttempts)) {
        // 计算还需要等待多久才能发送下一次请求
        $waitTime = RateLimiter::availableIn($limiterKey);
        // 等待指定秒数
        sleep($waitTime);
        // 等待后再次检查(递归调用,直到可以请求)
        return $this->allowRequest();
    }

    // 记录这次请求(增加计数)
    RateLimiter::hit($limiterKey, $decaySeconds);
    return true;
}

额外优化:防止无限等待

如果不想让请求无限等待下去,可以用waitUntil方法设置超时时间,比如最多等5分钟:

use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Carbon;

protected function sendRequest()
{
    // 尝试等待5分钟,如果还是无法请求就抛出异常
    if (!RateLimiter::waitUntil('external-api-requests', 25, Carbon::now()->addMinutes(5))) {
        throw new \Exception('请求过于频繁,请5分钟后再试');
    }

    // 执行API调用
}

注意事项

  • 缓存驱动:RateLimiter依赖Laravel的缓存系统,默认用文件缓存,单服务器环境没问题;如果是多服务器部署,要换成Redis或Memcached这类分布式缓存,不然每个服务器会各自计数,导致总请求量超过限制。
  • 限流key:'external-api-requests'这个key可以根据你的需求修改,比如如果不同用户有不同的限流规则,可以把用户ID加入key中(比如'external-api-requests-' . auth()->id())。

内容的提问来源于stack exchange,提问作者Jjj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:37:40