Amazon Web Services ブログ
AWS Virtual Waiting Roomのご紹介
この記事は、プリンシパル・ソリューションズ・アーキテクトのジャスティン・ピルトル、ソフトウェア開発エンジニアのジョーン・モーガン、ソフトウェア開発エンジニアのジム・タリオが執筆しています。
本日、AWS は公式の AWS Virtual Waiting Room (仮想待合室)ソリューションをご紹介します。このオープンソースのソリューションは既存のウェブアプリケーションやモバイルアプリケーションと統合し、需要のピーク時や突然のトラフィックバースト時にユーザーをバッファリングし、システムのリソースが枯渇するのを防ぐことができます。
一般的に、需要が不明な場合や大量のトラフィックが予想される様なイベントの場合に、仮想待合室が使用されます。このようなイベントの例としては、コンサートチケットの販売、ブラックフライデーのプロモーション、COVID-19ワクチンの登録などがあります。仮想待合室を使うことで、一定数のユーザ毎に購入操作などのトランザクションを表示、選択、完了させることができます。待合室にいるユーザーを順番待ちになるまでバッファリングすることで、アプリケーションのバックエンド環境をトラフィックから保護します。
物理的な待合室や順番待ちで番号札を受け取る様に、ユーザーは AWS 仮想待合室に入ると順番に番号を取得します。一意のデバイス ID に対応する番号を受け取ると、ブラウザは定期的にポーリングして更新を確認します。この更新で、現在対応されている番号と、最前列に到達するまでの予想時間が表示されます。
最前列に到達すると、ユーザーは番号とデバイス ID をセキュアなセッショントークンと交換できます。このトークンは、ユーザーを認証する際のダウンストリームのリクエストに含まれます。
ユーザーがバックエンドのエンドポイントを発見して直接リクエストを送信しようとすると、待合室にリダイレクトされます。API リクエストは、有効なトークンを取得するまでアクセスを拒否されます。これにより、バックエンドを一度にすべてのユーザーに対応できるように拡張する必要がなくなります。
AWS 仮想待合室をアプリケーションに統合する
アプリケーションへ統合する手順は、統合の方法によって異なります。すべてのユーザーを待合室にルーティングするのか、トラフィックが多いときだけルーティングするのかを決めることができます。また、バックエンドのウェブページを提供するウェブホストのみを保護するか、バックエンドのサービスの複数の API を保護するかを選択することもできます。
待合室をアプリケーションに統合するには、次の 4 つの一般的な方法がサポートされています。
- ターゲットサイトからのすべてのトラフィックを、AWS Virtual Waiting Room を経由するようにアップストリームの通信をリダイレクトします。このオプションでは、すべてのユーザが待合室経由でアクセスし、許可された数だけ保護対象システムに送信されます。トラフィックは透過的に通過し、残りのユーザーをバッファリングします。キャパシティが利用可能になると、新規ユーザーを受け入れます。ターゲットサイトには、待合室を通過したユーザーのみがアクセスできます。
- ターゲットサイトから仮想待合室へダウンストリームのリダイレクトをします。このオプションでは、すべてのトラフィックをターゲットサイトに送信します。ターゲットサイトは、待合室に入る必要があるリクエストを条件に応じてリダイレクトします。DNS やアップストリームの変更は必要ありません。ターゲットサイトは、最初のユーザーリクエストとリダイレクト応答を処理できなければなりません。
- ターゲットサイト API と直接統合し、リダイレクトなしで既存のWebサイトのユーザーをバッファリングします。ウェブまたはモバイルアプリケーションを、API レベルで仮想待合室と統合します。別の待合室エンドポイントやサイトへのリダイレクトは必要ありません。これにより、シームレスなユーザーエクスペリエンスを提供できますが、統合のためにより多くの開発が必要になる場合があります。
- OpenID 接続 (OIDC) アダプターを利用する。このオプションでは、待合室と Application Load Balancer (ALB) などの OpenID Connect 対応システムコンポーネントをコードなしでネイティブに統合できます。ユーザーは、ロードバランサーまたは同様のコンポーネントによって待合室にリダイレクトされ、署名された期限付きの JSON Web トークン (JWT) が発行されるまでバッファされます。ユーザーの JWT トークンが発行されると、ロードバランサーはユーザーリクエストをターゲットのバックエンドシステムに転送します。
AWS 仮想待合室ソリューションの概要
AWS 仮想待合室ソリューションの実装には、次の 3 つの主要コンポーネントが含まれます。
- コア API : デプロイされる主なリソースには、2 つの Amazon API Gateway 、1 つの VPC 、複数の AWS Lambda 関数、 Amazon DynamoDB テーブル、および Amazon ElastiCache クラスターが含まれます。 この API は、待合室に入るクライアントを追跡するための基本的なメカニズムを提供します。保護対象のサイトに入る為には、待ちの順位と認証トークンを必要とします。
- 待合室のフロントエンド Web サイト: 待合室の静的サイトは、順番待ちのユーザーに表示されます。このサイトは、設定した間隔で、現在の順位を動的に更新します。このサイトの HTML 、CSS 、JavaScript はフロントエンドのスタイルやテーマに合わせてカスタマイズできます。
- 保護されたターゲットシステム用の Lambda オーソライザー: Lambda オーソライザーは、ダウンストリームの保護対象のシステムの API をラップすることで保護します。これにより、すべてのユーザー呼び出しに、Waiting room Core APIによって発行された検証済み期限付きトークンが確実に含まれるようになります。これにより、ユーザーが待合室を迂回するのを防ぎます。
AWS仮想待合室の CloudFormation テンプレートは、次のインフラストラクチャをデプロイします。
- クライアントがパブリック API を呼び出すための Amazon CloudFront ディストリビューション。
- 仮想待合室からのキューリクエストを処理し、順位を追跡し、ターゲットウェブサイトへのアクセスを許可するトークンを検証する為の Amazon API Gateway パブリック API リソース。
- キューメッセージを処理する AWS Lambda 関数へのトラフィックを制限する Amazon Simple Queue Service (Amazon SQS) キュー。リクエストごとに Lambda 関数を呼び出すのではなく、SQS キューは一気に送信されるリクエストをバッチで処理します。
- 管理機能のための API Gatewayプライベート API リソース。
- パブリックおよびプライベートの API リクエストを検証して処理し、適切なレスポンスを返すための Lambda 関数。
- Amazon ElastiCache for Redis クラスターと直接やり取りする Lambda 関数を配置するための Amazon Virtual Private Cloud (VPC)。VPC エンドポイントにより、VPC 内の Lambda 関数はソリューション内のサービスと通信できます。
- Amazon EventBridge のカスタムイベントバスと連携してステータスの更新を定期的にブロードキャストする Lambda 関数を呼び出す Amazon CloudWatch ルール。
- トークンデータを保存する Amazon DynamoDB テーブル。
- トークン操作やその他の機密データを保存するためのキーを保存するAWS Secrets Manager 。
- (オプション) AWS Identity and Access Management (IAM) ロールと Lambda 関数で構成される API 呼び出しの署名を検証するオーソライザーコンポーネント。このオーソライザーが API を保護するための唯一の要件は、API Gateway を使用することです。
- (オプション) 2 つのインレット(滞留)ストラテジーをサポートする為の Amazon Simple Notification Service (Amazon SNS) 、CloudWatch 、および Lambda 関数。
- (オプション) OpenID プロバイダーがウェブサイトへのユーザーを認証するための API Gateway と Lambda 関数を備えた OpenID アダプタコンポーネント。このコンポーネントの待合室ページの為のCloudFront ディストリビューションと Amazon Simple Storage Service (Amazon S3) バケット。
- (オプション) サンプルのイベントサイトのための Amazon S3 オリジンバケットと CloudFront ディストリビューション。
AWS 仮想待合室のデプロイ
AWS 仮想待合室を使用するには、「Getting Started」 のスタックをデプロイします。これにより、コア API スタック、オーソライザースタック、およびサンプルアプリケーションの CloudFormation スタックがデプロイされます。
- 「Getting Started」 の CloudFormation スタックを起動します。 テンプレートはデフォルトで米国東部 (バージニア北部) リージョンで起動します。別の AWS リージョンでソリューションを起動するには、コンソールのナビゲーションバーから対象のリージョンを選択します。
- [スタックの作成] ページで、 [Amazon S3 URL] テキストボックスに正しいテンプレート URL が入っていることを確認し、[次へ] を選択します。
- [スタックの詳細を指定] ページで、ソリューションスタックに名前を割り当て、すべてのデフォルトパラメータ値をそのまま使用します。文字の制限については、 AWS Identity and Access Management ユーザーガイドの IAM と STS の制限を参照してください。[次へ] を選択します。
- [スタックオプションの設定] ページで、 [次へ] を選択します。
- レビューページで、設定を確認します。チェックボックス 「AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。」にチェックを入れます。
- [スタックの作成] を選択してスタックをデプロイします。
- スタックのステータスは、AWS CloudFormation コンソールの [ステータス] 列で確認できます。約 30 分後に CREATE_COMPLETE ステータスが表示されるはずです。
- 正常にデプロイされたら、 [出力] タブを開きます。
- [ControlPanelURL] と [waitingRoomURL] の値をメモ帳などにコピーして、後で使用できるようにします。
AWS 仮想待合室の設定
3 つのスタックをデプロイしたら、サンプルアプリケーションを使用して待合室をテストします。
- IAM コンソールに移動します。待合室スタックをデプロイしたのと同じアカウントで、新しい IAM ユーザーを作成するか、既存の IAM ユーザーを選択します。
- 選択した IAM ユーザーに、プログラムによるアクセス権限を付与します。キーファイルをダウンロードするか、後で使用できるようにアクセスキー ID とシークレットアクセスキーの値をメモしておきます。
- この IAM ユーザを「 Getting Started 」の [CoreModuleStack] で作成された [ProtectedApiGroup] IAM ユーザーグループに追加します。
- 以前に保存した [ControlPanelURL] を新しいタブまたはブラウザウィンドウで開きます。
- コントロールパネルの [show] ボタンを押して、[設定] セクションを展開します。
- IAM で保護された API を呼び出す為に、2でメモしたアクセスキー ID とシークレットアクセスキーを入力します。エンドポイントとイベント ID は URL パラメータから入力されます。
- [use] ボタンを選択します。 認証情報を入力すると、ボタンがアクティブになります。
- 表示されたメトリクスの後ろに、「 Connected 」というステータスが表示されるようになります。
サンプル待合室のテスト
- 新しいブラウザタブでサンプル待合室を開きます。CloudFormation スタックの出力からメモしておいた [WaitingRoomURL] を使用してください。
- [Reserve] ボタンを選択して待合室に入ります。取引を進められないのは、順番が割り当てられた番号に達していないからです。
- コントロールパネルでブラウザタブに戻ります。
- [Increment Serving Counter] で、[Change] ボタンを押します。これにより、サービングカウンターが手動で増え、100 人のユーザーが待合室からターゲットサイトに移動できるようになります。
- 待合室に戻り、 [Check out now!] ボタンを押してください。順番が割り当てられた番号に達し、取引を進める権利を得られた為、ターゲットサイトにリダイレクトされます。
- ターゲットサイトでの取引を完了するには、[Purchase now] ボタンを押します。このページは、待合室の向こう側にあるECサイトやイベントページなどにあたる、保護対象システムのサンプルです。これを、実際に保護しようとする対象のシステムと置き換えてください。
- 疑似的な購入処理が完了すると、トランザクションが成功したことが分かります。このトランザクションは、以前に待合室から送られてきた期限付き認証トークンを使用して承認されます。ユーザーが待合室を迂回してアクセスした場合には、取引は正常に完了しません。
あなたのアプリケーション用の AWS 仮想待合室のカスタマイズ
このサンプルのブラウザクライアントは、AWS Virtual Waiting Room を使ったECサイトでの購入フロー全体を示しています。このコードを待合室の手始めとして使うことも、API 関連のコードを参照して待合室を既存の Web サイトに統合することもできます。
サンプルコードは、ユーザーインターフェイスをレンダリングするために Vue.js と Bootstrap でビルドされています。Axios と Axios-Retry パッケージを使用して、仮想待合室スタックへのAPI呼び出しを行います。Axios-Retry パッケージを使用して、トラフィックの多い状況でのスロットリング条件と指数関数的バックオフ( exponential backoff )の処理方法を示しています。
コントロールパネルクライアントは、IAM ベースの認証を必要とするプライベート待合室 API にリクエストを送信するために使用されます。コントロールパネルクライアントは、プライベート API へのリクエストを作成して署名する方法を示しています。本番環境で使用することも、さらにカスタマイズすることもできます。ブラウザクライアントとコントロールパネルクライアントを含んだ、すべてのサンプルソースコードは GitHub で入手できます。
まとめ
AWS 仮想待合室ソリューションは、 Apache 2 ライセンスのもとでオープンソースとして提供され、追加費用なしでご利用いただけます。さまざまな方法で、あらゆるフロントエンドアプリケーションとのカスタマイズされた統合をサポートします。また、さまざまなインレット(滞留)ストラテジーを使用して、ユーザーが保護対象システムに入るのを待合室でいつどのように許可するかをカスタマイズすることもできます。
AWS Virtual Waiting Room ソリューションの詳細については、ソリューション実装および実装ガイドをご覧ください。
その他のサーバーレス学習リソースについては、 Serverless Land をご覧ください。
翻訳は Solutions Architect 多田が担当しました。原文はこちらです。