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
相关产品推荐
相关产品推荐

