その他

【Laravel・AWS】アプリケーションからメールが送信できない

その他
この記事は約3分で読めます。

AWSにデプロイしたLaravelアプリケーションからメールが送信できない事象が発生しました。

調査した点、原因について解説します。

発生したことの詳細

AWSにデプロイ済みのLaravelアプリケーションからメールが送信できていないことが確認されました。
アプリケーションには本番環境とステージング環境がありますが、ステージング環境でのみ発生していました。

本番環境ではメールが送信され受信できています。
そのため、この問題は以前から認知されていましたが放置されていました。

今回、他の機能の改修の動作確認のために必要になったので修正することになりました。

アプリケーションの構成

・本番用とステージング用のEC2インスタンス、RDSインスタンスが用意されています。

・双方がひとつのSESインスタンスを用いてメール送信を行っています。

調査した点、原因

本番用とステージング用のソースコードに差異がないことは確認しています。
.envファイルにも、別々に用意したAWSインスタンスに関係しない点に差異はありませんでした。
プロジェクトファイルに問題はないということになります。

続いて、AWSインスタンスの設定を確認します。
VPCなどの設定に問題はなく、各インスタンスが正しく接続されている様子でした。

Laravelのソースコードのところどころにログ出力を設定します。
既に、送信ボタン押下時にフォーム内容を出力するログは設定されていました。
・送信先のアドレスを入力するフォーム画面に遷移したときに確認ログ
・送信先の情報を確認する画面に遷移したときにフォーム内容を出力
を新たに加えました。
しかし、すべてのログが正しく出力されています。

そこで、より細かくメール送信処理にログ出力を挟みました。
送信ボタン押下
→アカウント権限を確認、権限不足ならエラー処理
→既に送信先アドレス向けのメールが作成済みか確認
→作成済み、未作成に応じて本文が異なるメール作成関数を発火
→メールを作成し送信処理を非同期処理のキューに追加
すると、キューに追加する処理付近に挟んだログのみが出力されていませんでした。

ここで本番環境とステージング環境の差異が見つかります。
メールの送信処理を行うクラスインスタンスを非同期処理のキューに渡しているのですが、インスタンスのプロセスを確認するとこれを処理するプロセスがステージング環境では動いていませんでした。
具体的にはphp artisan queue:workが動いていませんでした。

試しにコマンドを実行するとすぐに二十数件のメールが送信されました。
SESのパフォーマンスに影響するので止めておきます。

しかし、プロセスが停止していた原因は特定できていません。
いかんせん、いつから発生していた問題なのかが分からず、特定するための情報が少ないのです。
恐らくphp artisan queue:restartを実行したのでしょう。
restartという見かけに反して停止するためのコマンドのため、変更を加えたあとにプロセスを再起動しようとしたのかもしれません。

前述則りSESの送信上限やスパム評価などに影響するため、単にプロセスを再度動かすだけでは最善ではありません。
直接キューを全削除してからプロセスを再起動するのがよいでしょう。

復旧方法

今回のケースはsupervisordを用いてphp artisan queue:workをデーモン化して実行していたので、再度supervisordを動かすだけで解決しました。

改めて原因

アプリケーションからメールが送信されなかった原因は、メール送信処理のキューが処理されず溜め込まれていたことでした。
なぜキューの処理が止まっていたのかは未だ不明です。