FURYU Tech Blog - フリュー株式会社

フリュー株式会社の開発者が技術情報を発信するブログです。

SES→S3→SNS→SQS→Step Functionsで作る「破綻しないメール処理フロー」実践記

フリュー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に関しても頭を抱えたエピソードがあるので機会があればまた記事にさせていただきます。では。