Works
配信連動サービスのサーバーレス移行
配信者ごとにコンテナを常駐させていた構成を、イベントが来たときだけ動くサーバーレス構成に作り替え。月額インフラ費用を約4割削減。
- INDUSTRY
- ライブ配信
- SCOPE
- 現状調査 / アーキテクチャ設計 / 実装 / インフラ構築 / 移行
- PERIOD
- 2026年4月
- TEAM
- 1名 + AI
- STACK
- AWS Lambda / API Gateway / DynamoDB / RDS
01課題
- 配信者 1 人につき 1 つのコンテナを常に動かしており、配信者が増えるほど費用と運用の手間が増える構造だった
- 新規登録のたびに、イメージのビルド → ECR への push → タスク起動 → ロードバランサーへの登録を、バッチサーバーで順に実行する必要があった
- MySQL 8.0 の延長サポート料金が加わり、2026年8月には月額費用が移行前の約 1.8 倍に膨らんだ
02対応
- 移行前の構成を 1 名で構築・運用してきた経験をもとに、移行後の構成を 1 名 + AI で設計から実装・移行まで行った
- チャットの受信を、常時接続の IRC から Twitch EventSub(Webhook)に切り替え、API Gateway で受けて Lambda 1 本で処理する形にした
- OBS への配信を API Gateway の WebSocket に移し、接続の管理を DynamoDB に任せた
- 配信者の追加は「S3 に chat.js を生成し、EventSub 5 種を自動登録する」だけにし、ビルドもコンテナ起動もなくした
- cron で動かしていた定期ジョブを、EventBridge から起動する Lambda 5 本に分けた
- RDS を MySQL 8.4 にアップグレードし、不要になったリソースを削除。全体を CloudFormation で一括デプロイできるようにした
03成果
約4割減
月額インフラ費用
移行前と比べて。費用が膨らんだ時期と比べると約 3 分の 2 を削減
N → 1
イベント処理の実行単位
配信者ごとのコンテナを Lambda 1 本に集約
即時
新しい配信者の準備
ビルドとコンテナ起動が不要に
Architecture
の担当
新規
変更
廃止
担当部分にカーソルを合わせる(タップする)と、できることが表示されます
の担当
新規
変更
廃止
担当部分にカーソルを合わせる(タップする)と、できることが表示されます
構成の変化
subroq の担当部分にカーソルを合わせる(タップする)と、行った作業が表示されます。
移行前の構成(常駐コンテナ / 1 名で構築)
の担当
新規
変更
廃止
担当部分にカーソルを合わせる(タップする)と、できることが表示されます
CloudFront
- オーバーレイ用の HTML / JavaScript を配信します
S3
- 配信者ごとに生成した chat.js を保存します
SQS(起動要求キュー)
- 新規登録や再ビルドの要求を、管理画面から積んでいました
ECR
- 配信者ごとの Docker イメージを保管していました
ALB
- URL のパスで、配信者ごとのコンテナに振り分けていました
- 配信者が増えるたびにターゲットグループを追加していました
ECS タスク(配信者ごとに常駐)
- 配信者 1 人につき 1 コンテナが常に動いていました
- 配信者が増えるほど、費用と運用の手間が増える構造でした
EC2(管理画面)
- 配信者の登録・設定を受け付けます
- chat.js を生成し、コンテナの起動要求を出していました
RDS(MySQL 8.0)
- 配信者の設定やイベントを保存します
- MySQL 8.0 は延長サポートの追加料金が発生していました
EC2 バッチ(2 台)
- SQS を見張り、build → ECR push → タスク起動 → ターゲット登録を順に実行していました
- 定期ジョブもこのサーバーの cron で動かしていました
移行後の構成(サーバーレス / 1 名 + AI で構築)
の担当
新規
変更
廃止
担当部分にカーソルを合わせる(タップする)と、できることが表示されます
CloudFront
- オーバーレイ用の HTML / JavaScript を配信します
S3
- 配信者の登録時に生成した chat.js を保存します
- これだけで新しい配信者の準備が完了します
API Gateway(WebSocket)
- OBS との WebSocket 接続を AWS のマネージドサービスで受け持ちます
- サーバーを常駐させずに、リアルタイム配信を実現しています
Lambda(ws-*)
- WebSocket の接続・切断を処理し、接続 ID を記録します
DynamoDB(WebSocket 接続管理)
- どの OBS がどの配信者につながっているかを管理します
- イベントを処理する Lambda が、ここから送り先を引きます
API Gateway(REST)
- Twitch EventSub からの Webhook を受け付けます
EventBridge
- cron で動かしていた定期ジョブを、スケジュール実行に置き換えました
EC2(管理画面)
- 配信者の登録時に chat.js を生成し、EventSub を自動登録します
- コンテナを起動する処理はなくなりました
RDS(MySQL 8.4)
- MySQL 8.0 から 8.4 にアップグレードし、延長サポートの追加料金をなくしました
- 使われていなかった RDS Proxy を削除しました
Lambda(eventsub-webhook)
- すべての配信者のイベントを、この 1 本の関数で処理します
- DB に書き込み、WebSocket で OBS に push します
- イベントが来たときだけ動くので、待機中の費用はかかりません
Lambda(定期ジョブ ×5)
- バッチサーバーの cron で動いていた処理を、5 本の関数に分けました
- バッチ用の EC2 は不要になりました
NAT インスタンス
- VPC 内の Lambda が外部 API を呼ぶための出口です
- NAT Gateway ではなく t3.nano のインスタンスにして、費用を抑えています
何が変わったか
| 役割 | 移行前 | 移行後 |
|---|---|---|
| チャット受信 | IRC に配信者ごとに常時接続 | EventSub Webhook → API Gateway REST |
| イベント処理 | 配信者ごとの ECS コンテナ ×N | Lambda(eventsub-webhook)1 本 |
| OBS への配信 | ALB + Socket.IO(配信者ごとにターゲットグループ) | API Gateway WebSocket + DynamoDB |
| 配信者の追加 | SQS → バッチ EC2 で docker build → ECR → ECS | S3 に chat.js を生成 + EventSub 5 種を自動登録 |
| 定期ジョブ | バッチ EC2 の cron | EventBridge → Lambda ×5 |
| データベース | MySQL 8.0(延長サポート課金) | MySQL 8.4 |
| デプロイ | イメージの再ビルドとタスクの再起動 | CloudFormation で一括デプロイ |