こんにちは、レムシステム株式会社のエンジニア、小村(@system_kom)です。今回は、Webサービスの開発会社様が提供する会員制のリアルタイムWebサービスを、AWS上に構築・移行した事例をご紹介します。
ルームやチャット、ランキングといった機能はWebSocketによる常時接続で動いています。WebSocketをどこで動かすか、複数台のサーバー間でどう配信をそろえるか、そして何台あれば足りるのか。設計から本番前の負荷試験までの流れをまとめました。
要件と課題
| 項目 | 内容 |
|---|---|
| アプリケーション | CakePHP(PHP-FPM)によるWebアプリと、Node.jsによるWebSocketサーバー |
| リアルタイム機能 | ルーム・チャット・ランキング。複数台のサーバーにまたがる配信同期が必要 |
| 移行元 | CentOS Stream 9 上の既存環境(nginx、PHP、Node.js、Redis、MySQL) |
| 運用 | OS上のcronで動いていた定期処理、監視、バックアップを含めて移行 |
WebSocket方式の比較
提案段階で、WebSocketの実現方法を3案比較しました。
| 観点 | A:API Gateway+Lambda | B:Web用EC2に同居 | B':WebSocket専用EC2(採用) |
|---|---|---|---|
| 開発 | 配信ロジックを別の仕組みで実装 | 既存の知識で開発可能 | 既存の知識で開発可能 |
| Web処理への影響 | なし | 常時接続とリソースが競合 | 専用EC2に分離して影響なし |
| デプロイ時の切断 | 影響なし | Web側のデプロイで切断 | Web側のデプロイの影響を受けない |
| 運用 | サーバー管理不要 | プロセス監視が必要 | プロセス監視が必要(WS専用EC2のみ) |
| スケール | 自動 | Web/WS一体で増設 | WS専用EC2だけ独立して増設 |
| 制約 | アイドル10分・最大2時間で切断 | ALBのタイムアウトと再接続の設計が必要 | 同左 |
開発会社様の既存の知識を活かせて、Web処理とWebSocketが互いに影響しないB'を採用しました。
構成と設計のポイント
| 項目 | 設計内容 |
|---|---|
| ネットワーク | VPCを新規作成し、サブネットは3AZ分を用意。EC2とALBは2AZに配置 |
| NAT Gateway | 使わない。EC2はパブリックサブネットに置き、セキュリティグループでALBからの通信だけを許可 |
| 振り分け | ALBのホストベースルーティングで、Web用とWebSocket用のFQDNを別々のターゲットグループへ |
| WebSocketサーバー | nginxがALBから80番で受け、ループバックのNode.jsへ中継。TLSはALBで終端 |
| プロセス管理 | AL2023にsupervisorがないため、pm2+systemdで常駐・自動再起動 |
| 配信同期 | ElastiCache(Valkey)のPub/Subで、複数台のWebSocketサーバー間のメッセージをそろえる |
| セッション | WebとWebSocketが同じValkeyのセッションを参照 |
| 接続維持 | 30秒間隔のPing/Pongと、指数バックオフによる自動再接続 |
| 静的コンテンツ | S3+CloudFront(OAC)。効果音などを別オリジンから取得するためのCORSはレスポンスヘッダーポリシーで設定 |
| 管理接続 | SSM Session Managerを標準とし、SSHは固定IPからの公開鍵認証のみ |
移行で調整したポイント
既存環境の設定をそのまま持ち込めない箇所がいくつかありました。
| 項目 | 移行元 | AWS環境での対応 |
|---|---|---|
| OS | CentOS Stream 9 | Amazon Linux 2023(arm64)。SSM Agent同梱、AWS公式サポートを重視 |
| 常駐管理 | supervisor | pm2+systemd |
| キャッシュ | Redis | ElastiCache(Valkey)。maxmemory-policy は移行元に合わせて allkeys-lru |
| DBの照合順序 | 日本語の照合順序を指定 | Aurora側で受け付けられない照合順序があり、移行元に合わせて作り直し |
| DBのパラメータ | my.cnf | 一部はクラスター単位で指定できず、インスタンス単位のパラメータで設定 |
| 定期処理 | OSのcrontab | EventBridge Scheduler から SSM Run Command を実行。対象はEC2タグで指定し、インスタンスを入れ替えてもタグの付け替えだけで済む |
| バックアップ | — | DLMで日次取得。スナップショットではなくAMIで保管し、そのまま起動して復旧できるように |
5,000人規模の負荷試験で分かったこと
運用開始の前に、WebSocketの分散負荷試験を行いました。
| 試験で見えたこと | 対応 |
|---|---|
| Node.jsをクラスターモードにしても、t4g.small(2GiB)ではメモリが不足 | WebSocketサーバーを t4g.medium(4GiB)に変更 |
| 2台構成では、4,050人の試験でCPU使用率が90〜100%に達し、一時的にUnhealthyになるインスタンスが出た | 同じ構成のAMIから2台を複製し、4台構成で運用開始 |
| 初期段階でDBコネクションの枯渇を疑い、Auroraを上位クラスへ変更 | 後に、本当のボトルネックはDBではなく、クライアント側のバックプレッシャーと試験のarrivalRate設定だったと判明 |
3つ目は正直な反省点です。負荷試験では、サーバー側の指標だけでなく、試験ツール側が想定どおりの負荷を出せているかを最初に確認すべきでした。WebSocketの負荷試験では、クライアント側の処理が詰まると、サーバーの限界より先に試験側が頭打ちになります。
監視と通知
CloudWatch Agentで、OSログ、nginx、PHP-FPM、WebSocketアプリのログをCloudWatch Logsへ集約しました。EC2やAuroraなどのアラームはSNSでメール通知し、お客様の指定アドレスに加えて当社でも受け取れるようにしています。
導入効果
| 項目 | 導入後の状態 |
|---|---|
| 同時接続 | 負荷試験の結果をもとに、WebSocketサーバーを4台に増強した構成で運用開始 |
| 可用性 | Web・WebSocketとも2AZに分散し、ALB配下で冗長化 |
| スケール | 接続数の増加には、WebSocket専用EC2の増設だけで対応できる |
| 運用 | 定期処理・バックアップ・監視通知をAWSのマネージドサービスで自動化 |
レムシステムのAWS構築支援
レムシステムでは、AWS環境の方式検討・設計書の作成から、構築、負荷試験、運用設計までを一貫して対応しています。WebSocketを使ったリアルタイムサービスや、既存サーバーからAWSへの移行もお任せください。開発会社様のインフラパートナーとしてのご相談も承っています。
静岡県・東海エリアを中心に、オンラインで全国からのご相談に対応しています。