負荷試験中にLaravelのAPIから429 Too Many Requestsが返るようになった。 当初、AWS EC2のt2.microの環境だったため負荷試験申請していないことが原因かと思い、はまってしまった。
原因を突き詰めると、Laravelのデフォルトでリクエスト数制限を掛ける処理になっているようです。
環境
- php 7.3
- Laravel 5.8
原因:ThrottleRequests
\app\Http\Kernel.php
にあるmiddlewareGroupsの設定に、API数を制限する記述があります。
'throttle:60,1'
が同一のIPアドレスとドメインから1分間に60回までのリクエスト数に制限しています。
protected $middlewareGroups = [
// 省略
// 40行目付近
'api' => [
'throttle:60,1', // 1分間に60回まで
'bindings',
],
throttleは$routeMiddleware`の中でvendorにあるモジュールを定義していました。
protected $routeMiddleware = [
// 省略
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
x-ratelimit-limit
throttleが有効になっている場合、HTTP Response Headersにx-ratelimit-limitとx-ratelimit-remainingが付きます。
- x-ratelimit-limit : リクエスト数上限
- x-ratelimit-remainin : 残りのリクエスト数
ThrottleRequests - GitHubの処理
\Illuminate\Routing\Middleware\ThrottleRequests::class
リクエスト元は、IPアドレスとドメインのハッシュキーから識別しているようです。
protected function resolveRequestSignature($request)
{
if ($user = $request->user()) {
return sha1($user->getAuthIdentifier());
}
if ($route = $request->route()) {
// IPアドレスとドメインのハッシュ
return sha1($route->getDomain().'|'.$request->ip());
}
throw new RuntimeException('Unable to generate the request signature. Route unavailable.');
}
また、RateLimiterというキャッシュストアを使ってリクエスト数をカウントしていました。
解消法
'throttle:60,1'
の数値を緩和するか、この行を削除したら制限がなくなります。
参考
このコードは初めて見た。。。 AWSのAPI Gatewayでもよくみられるようです。
ThrottleRequestsについてたくさんの検証をされています。 日本語記事があって有難い。
【TypeScript】Jestでdescribeなどの関数がnot findになってるのを解消する
TypeScriptテストエラー解消schedule2021-10-10
【TypeScript】JestでインポートしたモジュールがCannot find moduleとなるエラー
TypeScriptテストエラー解消schedule2021-10-10
laravel newコマンドでbash:laravel:command not found
Laravelschedule2020-10-05
LaravelのModelsのディレクトリ構成を変更する
Laravelschedule2020-09-02
【Laravel】UserAgentでガラケー用のViewを切り替えるためのmiddleware
Laravelschedule2020-04-21