フリューAdvent Calendar 2025 の17日目の記事となります。
こんにちは!フリュー株式会社 にぎやかし担当 森田です!
今回は たった1通のメールを処理するためにAWSをどう組み合わせてフローを作ったか
そしてその中で気づいた「落とし穴と学び」について書きます。
📩 要件
- 複数アドレスでメールを受信したい
- 添付ファイルを抽出して保存したい
- 本文を解析して必要な情報を取り出したい
- 取り出した情報を DB に登録したい
つまり
メール受信 ⇒ 格納 ⇒ 通知 ⇒ 分解 ⇒ 登録
という流れを 安全・確実・再実行可能 にする必要があります。
🛠 最初に考えた構成
- SES:メール受信
- S3:メール保存
- SNS:イベント通知
- SQS:処理キュー(DLQ付き)
- Lambda:解析して DB登録
- Aurora MySQL:保存先
当時の私はこう思いました。
「完璧なフローのできあがりや…!!!!」
しかし、メール解析Lambda実装中に気づいてしまったんです!!!!
😨 “なんでも屋Lambda” が爆誕する未来が見えた
添付抽出、文字コード変換、本文抽出、DB登録…
これ全部を1つのLambdaに詰め込むと以下の不安が現実になります。
- 処理時間が伸びてタイムアウト
- コード肥大化でメンテ不能
- 将来の追加処理に対応しづらい
などなど。
そこで最近プロポーズして断られたChatGPTに相談したところ、出てきた答えが Step Functions でした。
🚀 Step Functions を挟むとこうなる(要点だけ)
✔ Lambda を処理単位で分割できる
✔ 各ステップが短時間で終わる
✔ どこで失敗したか可視化できる
✔ リトライ・エラー処理をステップ単位で設定できる
結果として、
巨大Lambdaが破綻する未来を避けられる
というわけです。
📘 Step Functions を入れた構成(簡略図)
graph LR
SES[SES] --> S3[S3]
S3 --> SNS[SNS]
SNS --> SQS[SQS]
SQS --> L0[入口Lambda]
subgraph SFN[Step Functions]
L0 --> L1[添付抽出Lambda]
L1 --> L2[本文解析Lambda]
L2 --> L3[DB登録Lambda]
L3 --> OK[Success]
L1 -->|Error| NG[DLQ]
L2 -->|Error| NG
L3 -->|Error| NG
end
Lambda の役割を分散できて、だいぶスッキリしました。
⚠ ……ただし、実はこれでも完全には解決していない
現状の構成では、
入口Lambdaが Step Functions の結果を“同期的に待っている” ため、
- 入口Lambdaの処理時間は長いまま
- SQS のメッセージ消化が詰まりやすい
という 根本問題は残っています。
ただし、各Lambdaが軽いため、
現段階ではボトルネックにはなっていない
という状態です。
(この記事書いてる時に気づいちゃうとはねぇ~…)
🔧 もし改善するならこうする
- 入口Lambdaは「Step Functions を起動するだけ」にする(非同期)
- 失敗時のDLQ制御は Step Functions 側に寄せる
- Lambda はできるだけ薄く保つ
こうすれば、よりスケーラブルで安定した処理フローになります。
🎉 まとめ
Step Functionsを使うことで1つのLambdaに全部押し込んで破綻する未来を避けることができました。
ただ、 入口Lambdaが結果待ちする構成では完全解決ではなかった
という学びもありました。
とはいえ「少しずつ構成を良くしていくプロセス」って面白いですよね。
今後も改善を続けていきたいと思います!
メール解析Lambdaに関しても頭を抱えたエピソードがあるので機会があればまた記事にさせていただきます。では。