Laravel API 限速异常 HTTPException Too Many Attemps

线上 Laravel 错误日志发现了一个异常

HTTPException Too Many Attemps

而我一个同事在本地开发的过程中也频繁遇到这个异常。测试环境:Laravel 5.5。


网上查了一下,是 Laravel 5.2 引入的 throttle middleware 造成的。


源码参考


https://github.com/illuminate/routing/blob/master/Middleware/ThrottleRequests.php


public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
其表现是在 HTTP 的 Response 头中缀上了请求次数统计


X-RateLimit-Limit:60
X-RateLimit-Remaining:59
从 Chrome 的 console 看,每个 API 请求都会占用这个 limit 的限额。


X-RateLimit-Limit:60
X-RateLimit-Remaining:53
等过一分钟,再发送一个请求,都会发现限额已经被自动恢复。

对应的配置在 Laravel 项目文件 app/Http/Kernel.php
'api' => [
  'throttle:60,1',
  'bindings',
]
所以,

第一个参数 60 代表每分钟限制 60 次请求
第二个参数 1 代表触发了限制规则,则1分钟内禁止访问

将 60 调整成 120 就可以保证本地 debug 不会被频繁限制了。


Laravel API 的访问频率限制使用中间件 throttle 实现。默认 throttle 限制每分钟最多尝试 60 次,超过这个限制后,会返回 429 异常(Too Many Requests),提示访问次数太多。


下面举两个例子。


限制每分钟访问 5 次
Route::group(['prefix'=>'api','middleware'=>'throttle:5'],function(){
    Route::get('/users/{user}', function (App\User $user) {
        dd($user);
    });
});
限制每分钟访问 5 次,超过次数后,等待 10 分钟方可继续使用 API
Route::group(['prefix'=>'api','middleware'=>'throttle:5,10'],function(){
    Route::get('/users/{user}', function (App\User $user) {
        dd($user);
    });
});

有话要说