解決したいこと
ユーザーのユーザー登録・認証を含むウェブサービスを提供しています。
フロントエンドは Nuxt.js
で、バックエンドは Laravel(5.8)
です。
今回は、そのバックエンドで以下のエラーが起きています。
発生している問題・エラーメッセージ
以下のログが不定期に残ります。
[2021-07-10 09:15:45] production.ERROR: Maximum execution time of 30 seconds exceeded {"exception":"[object] (Symfony\Component\Debug\Exception\FatalErrorException(code: 1): Maximum execution time of 30 seconds exceeded at /var/www/html/my-service/vendor/laravel/framework/src/Illuminate/Hashing/AbstractHasher.php:32) [stacktrace]
AbstractHasher.php
の32行目で、PHPの処理時間が php.ini
規程の 30s
を超えているため処理が中断されているという内容です。
該当のソースコード
以下の部分が該当するコードです。自分で書いたコードではなく、Laravelの vendor/
内部のコードです。
vendor/laravel/framework/src/Illuminate/Hashing/AbstractHasher.php
php
1/** 2 * Check the given plain value against a hash. 3 * 4 * @param string $value 5 * @param string $hashedValue 6 * @param array $options 7 * @return bool 8 */ 9 public function check($value, $hashedValue, array $options = []) 10 { 11 if (strlen($hashedValue) === 0) { 12 return false; 13 } 14 15 return password_verify($value, $hashedValue); // 32行目 16 }
認証の方法について
ユーザーはフロントエンドからユーザー名・パスワードを自分で設定してバックエンドに送信します。
バックエンドでは以下の処理によって平文パスワードをハッシュ化し、データベースに登録しています。
php
1use Illuminate\Support\Facades\Hash; 2... 3{ 4 ... 5 $user->password = Hash::make($password); 6 $user->save(); 7}
また、ユーザーの認証は以下の方法で行っています。
php
1public function login(Request $request) { 2 try { 3 $email = $request->input('email'); 4 $password = $request->input('password'); 5 6 if (!isset($email)) { 7 throw new \Exception('Error.'); 8 } 9 10 if (!isset($password)) { 11 throw new \Exception('Error.'); 12 } 13 14 $user = User::select('id', 'username', 'password') 15 ->where('email', $email) 16 ->first(); 17 18 if (!$user) { 19 throw new \Exception('Error.'); 20 } 21 22 if (Hash::check($password, $user->password)) { 23 // seccess! 24 return response('seccess', 200) 25 } else { 26 throw new \Exception('Error.'); 27 } 28 } catch { 29 30 } 31}
補足
php.ini
の設定を長くする(or 無制限にする)という解決策は最終手段としたいです。
その理由は以下の2点です。
- 本来であればこの
check()
の関数の処理に30秒もかかるとは思えない 30s
の設定をより長くしてもサーバーがダウンする問題は解決されないのではないかと考えている
そのため、より本質的に、この check()
に30秒もかかっていること自体にアプローチできる解決策を求めています。
このエラーログが数分おきに記録されるとき、サーバーが圧迫されたためバックエンドがレスポンスを返さなくなったことでAPIを取得できず、サービス(フロントエンド)がダウンしました。
エラーログは不定期で記録されます。サービスが本格的にダウンした時には、数分ごとに上記のログが残り、3時間ほどその状態が続きました。その間、全てのAPIを取得できませんでした。
Laravel の運用は数年やっておりますが、エラーログからも理由がわからず、サーバーログからも理由がわからず、サービスはダウンしてしまう、ということは久々です。有識者の方、ぜひ何かアイデアをご教授ください。
あなたの回答
tips
プレビュー