Web開発のしおりRepository

Webエンジニアリング関連の技術記事を掲載させていただいております。

実際に動いているチャットサービス(小規模)のインフラ構成を公開 | AWS イベントソーシング Auth0

はじめに

個人開発で制作し先日(2020/11/08)に初めのバージョンを公開したチャットサービス Someteria - Webサイト横断チャット (Chrome拡張) のインフラ構成を掲載します。 現状の総インストール数は8人(2020/11/10 時点)、生まれたてのサービスなので本格的な商業的サービスで適応できるかは保証しかねます。しかし、ミニマムにリアルタイムなメッセージの送受信基盤を作る際の一例として参考になれば幸いです。

インフラ構成図

Someteriaインフラ構成図

概略

  • AWSのサーバレスフレームワークのSAMを利用
    • Webサーバーの管理は基本しない
  • RESTfulなHTTP APIとしてのエンドポイントとWebSocketのエンドポイントがある
    • メッセージPush通知にWebSocketを利用
  • データストレージはDynamoDBとElasticsearchを利用
    • イベントソーシングの考えをベースにしている (後述)
  • 認証処理はAuth0 (IDaaSの一つ)を利用

DBまわり, イベントソーシング

書き込み要件と読み込み要件を分離するためにイベントソーシングのパターンを適応し、データソースを分けています。

流れ:

  1. API Gatewayから書き込み系の処理のLambdaを起動
  2. Lambdaから書き込みイベントをDynamoDBに保存
  3. DynamoDB Streamsをトリガーとして以下のLambdaをそれぞれ起動
    • Elasticsearchに表示用の非正規化されたデータを反映・構築
    • ブラウザに対してWebSocket経由で更新メッセージを送信
  4. 後ほど、読み込み系の処理のLambdaが表示用データにアクセス

少し回りくどくなりますが、1.の書き込み系の処理を行うLambdaと、3.の読み込み要件を担うLambdaとで関心を分離できます。そのおかげで実際の経験として、当初はブラウザからポーリングして取得していたデータを、サーバーからのプッシュにするようにする変更があったのですが、その際に1.の書き込み処理用のLambdaの変更は一切不要でした。

認証・ユーザ情報周り

Someteria Auth0

認証にはAuth0 (IDaaS)を利用し、Google, TwitterなどのプロバイダーとOpenID Connectのフローにより連携しています。 フロントのアプリケーションが直接Auth0のエンドポイントとやりとりし認証しトークン(JWT)を受け取ります。そのJWTをサーバーサイドに送りアクセス可否を判断します。

Elasticsearchへユーザー情報の同期

Auth0に保存されるユーザー情報(ユーザ名, アイコンURLなど)は、Auth0のログイン時に起動できるフックによってElasticsearchに同期しています。 Auth0上のユーザー情報はAuth0のAPIから直接アクセスもできます。しかしユーザー情報は頻繁にアクセスするのでAPIのレートリミットを超えないようにするためそうしています。

サーバープッシュ WebSocket

サーバープッシュ WebSocket

サーバーからのプッシュ通知はAPI GatewayのWebSocket APIを使用しています。クライアントがWebSocket APIに接続した際に得られるコネクションIDとメッセージサブスクリプションの情報をDynamoDBに保存します。後ほど、関連する更新イベントが起きた場合にコネクションIDを取得してクライアントに通知できます。

その他特徴

  • AWS Lambdaをベースとしたサーバレスアプリなので、サーバーのスケーリングをAWSに委ねられる
  • AWS SAMはCloudFormationによってコードベースでインフラを定義できるので、再現性が高い
    • ステージング環境などの複製環境をターミナルのコマンドから構築できる

まとめ

いかがだったでしょうか。チャットに限らず、リアルタイムなメッセージパッシングを実装する機会があれば、参考にしていただければと思います。

Web横断チャットサービスSometeriaも是非お試しください。

www.someteria.com