SQS + Lambdaでトランザクションメールを構築
背景
あるタイミングで一斉配信されるメールからWebページに遷移してコンテンツを取得する際に、ワンタイムパスワードでの本人確認機能を実現する必要がありました。ただし一斉配信されるメールによってアクセスが集中するため、高負荷でも問題なくサービスを利用できるような構成を目指す必要があります。また実際にメール送信を行うのは外部のSaaSを利用するのですが、SMTPのコネクション数に制限があるため、何も考えずにメールを大量送信することはできないため、何らかの制御を行う必要があります。
以上を踏まえて、ワンタイムパスワードメール配信の仕組みをAWS SQS と Lambdaを組み合わせて、サーバーレスの構成で実現しました。
サービスの構成
ワンタイムパスワードを発行するフローは以下のような構成で実現しています。詳細は割愛してますが、フロントエンドはAmplifyを利用し、バックエンドはServerless Frameworkを利用してAPI GatewayやDynamoDBを利用してフルサーバーレス構成としております。
SQSのイベントソースにLambdaを指定
通常はキューからメッセージを取得する処理をポーリング実行しますが、
LambdaをSQSのイベントソースマッピングに指定することで、イベントと共にLambdaを呼び出すことができます。ただしいくつか注意が必要です。
メッセージ配信が重複しないようにFIFOキューを利用する
lambdaで処理するバッチサイズを最大数設定する(FIFOの場合は10)
可視性タイムアウト、デットレターキュー、最大受信数を設定して、Lambdaの処理が失敗した場合のリトライ、エラーハンドリングを行う
SMTPサーバーへのコネクション数を制限するため、Lambdaの最大同時実行数を制限
SMTPサーバーへのコネクション数をコントロール
連続した時間で一つのメッセージに対して一つのSMTPコネクションを確立してメール送信をしてしまうと、コネクションが滞留したり、また単にコネクション数を制限するとメールが送信されるまでのパフォーマンスに影響が出ます。
負荷が高まったタイミングでは取得できる分のメッセージ(バッチサイズ)を一つでLambdaで取得し、SMTPコネクションを使い回して送信することでコネクション数を制限できます。これにより同時に確立されるコネクション数はLambdaの最大同時実行数分となります。
この記事が気に入ったらサポートをしてみませんか?