😱
Laravelで429エラーが出るときの対応
Laravelで開発・運用中のAPIサーバで、しばしば429エラーを観測するようになりました。
429エラーは「Too Many Requests」を示すので、トラフィックが激増したのかと思ったのですが、そういうわけでもなく。ではApacheの設定やサーバの設定を見直そうとしたものの、それらしい設定を見つけられず。
さてどうしたものか。
原因究明
さっぱりわからん…と頭を抱えていたところ、以下の記事を見つけました。ありがとうございます。
App/Providers/RouteServiceProvider.php
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
要するに「'api'の何かに対して、同一IDもしくは同一IPアドレスで1分間に60回以上アクセスしたら、アクセス制限を掛ける」というものです。
つまり、429エラーはソフトウェアで掛けているものだということが分かりました。
…あれ、このファイルって…?
実はこの現象が起きる前、この記事で対応した通り、 routes/web.php
でルーティングしていたAPIを、URLをそのままに routes/api.php
で送っているように余計なHTTPヘッダを付けないよう対応しておりました。
つまり、これまで'web'だったから大量のアクセスを受けても制限していなかったのが、'api'に切り替えたことで制限の対象になってしまったということですね。
解決
429エラーが出る前からサーバリソース的にはまあまあ余裕がありましたし、安直に閾値を実態に合わせてだいぶ大きくしてみました。
今のところ支障はありませんが、あまりに高負荷になる場合はまた何か考えないとですね。
App/Providers/RouteServiceProvider.php
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(300)->by($request->user()?->id ?: $request->ip());
});
Discussion