Amazon Web Services ブログ

Pegasystems 社による Amazon API Gateway における WebSocket のマルチテナントレート制限の管理方法

この記事は Steven Warwick, Solutions Architect – AWS と Josue Lima, Director of Software Engineering – Pega による共著を翻訳したものです。

Pegasystems は、オートメーション、エンゲージメント、ローコード開発を通じて、最も複雑なビジネス課題を単純化する AWS パートナーです。

Pega Digital Messaging Service によって、カスタマーサービスアプリケーションは、Apple Messages for Business、Facebook、SMS、WhatsApp、Twitter、Web チャットなどのデジタルチャネルを介して、シンプルで一貫した形式でメッセージを送受信することができます。各顧客はシステムのテナントとみなされ、一意の識別子で定義された複数のセッションを作成でき、また各セッションは複数の接続を作成できます。

マルチテナントのカスタマーサービスアプリケーションにおいて安定かつ一貫したパフォーマンスを提供するには、トラフィックの急増や予測不可能な負荷への対応が不可欠です。

例えば、Web チャットの会話中に、顧客は一意の識別子を使用して、複数の Web ブラウザタブとウィンドウを 1 つのセッションとして同時に使用することがあります。セッションを使うと、複数のブラウザタブまたはウィンドウ間でメッセージの状態を維持する柔軟性が提供できますが、開いているすべての接続で会話が維持されるため、メッセージレートが高くなります。

メッセージフラッディングはコールセンターの過負荷につながる可能性があり、一般的に新製品やサービスのリリース、プロモーション、顧客インシデントの際に発生します。

Amazon API Gateway には HTTP 接続で使用量プランを活用する手段がありますが、こちらは WebSocket では利用できません。代わりに API Gateway Lambda オーソライザーを使用することで、Pegasystems のお客様 (テナント) とセッションを検証し、接続レートとメッセージレートを制御できるようになります。

Amazon API Gateway には、処理できる 1 秒あたりの接続数に上限があります。テナントごとの接続レートを制御することで、各テナントは API Gateway の 1 秒あたりの合計接続数のうち特定の数を確保することができます。また、メッセージレート制限によって、メッセージを処理するダウンストリームのシステム負荷を制御できます。

ソリューション概要

この記事では、Pega Digital Messaging サービスがマルチテナントのインバウンド WebSocket 接続とメッセージレートを管理するために、Pegasystems がどのようにソリューションを構築したかについて説明します。

以下の図 1 に示すソリューションでは、Amazon Simple Queue Service (SQS) FIFO キュー、AWS Lambda、および Amazon DynamoDB を活用して、メッセージフロー全体を制御しています。Lambda 関数は、DynamoDB データベースに保存されているセッションとテナントのレート制限を確認および更新します。

これらのサービスが連携して、テナント固有のレートで接続とメッセージをスロットリングします。このソリューションのサンプルアプリケーションでは、サービス間の相互作用を確認することができます。

Amazon API Gateway の接続フェーズでは、インバウンド接続レートが制限されます。メッセージがダウンストリームのシステムに送信される前の処理段階では、メッセージレートが制限されます。

DynamoDB テーブル内の各テナントおよびセッションごとの接続レートとメッセージレートは、シンプルなトークンバケットアルゴリズムを用いてトラッキングされます。

接続とメッセージは次の 4 つの段階で処理されます。

  • 無効なテナントまたはセッションによる接続は拒否され、403 Forbidden のレスポンスを受け取る (以下の図 2 を参照)。
  • ユーザー接続が接続レート制限に達し、429 Too Many Requests レスポンスを受け取る (図 3 を参照)。
  • ユーザー接続がメッセージレート制限に達し、429 Too Many Requests レスポンスを受け取る。これにより、リソース使用量を下げるためそれ以降のメッセージ処理が停止する (図 4 を参照)。
  • ユーザー接続が成功し、スロットリングせずにメッセージが処理される (図 5 を参照)。

図 1 – Amazon API Gateway におけるWebSocket のマルチテナントレート制限アーキテクチャ

  1. クライアントは、Amazon API Gateway の HTTP エンドポイントに HTTP PUT リクエストを送信して、テナントのセッションを作成します。テナントは、オンボーディングプロセスの中で作成される一意の識別子によって定義されます (この記事では解説しません)。必要に応じてこの呼び出しを認証することもできますが、これについてもこの記事ではスコープ外とします。
  2. Lambda 関数はテナントのセッションを作成し、Time To Live (TTL) の値を指定して DynamoDB テーブルに保存します。Amazon DynamoDB Streams は、一定期間通信が送受信されなかった場合に、すべてのセッション接続を削除するために使用しています。データベース層への各呼び出しは、sts:TransitiveTagKeys を使用した条件キーによって制限しているため、各テナントは、テナント ID に基づく特定の行にのみアクセスできます。
  3. セッションが作成されると、クライアントは API Gateway の WebSocket エンドポイントに対して WebSocket 接続を開始します。セッションは、複数の Web ブラウザウィンドウから接続を作成するために繰り返し利用でき、これらの異なる接続の同期を維持するために使用されます。
  4. Lambda オーソライザーは WebSocket 接続のオーソライザーとして使用されます。オーソライザーは次のことを行います。
    • テナントが存在することの検証
    • セッションが存在することの検証
    • 認可コンテキストにテナント ID、セッション ID、接続 ID、およびテナント設定を追加
  5. $connect ルートに使用されるLambda 関数は、インバウンド接続をスロットリングし、制限を超えた場合は 429 のレスポンスコードを返します。具体的には以下の確認と処理が行われます。
    • このテナントに許可されている合計接続数を超えていないか
    • このセッションに許可されている合計接続数を超えていないか
    • このテナントに許可されている 1 分あたりの合計接続数を超えていないか
    • このセッションに許可されている 1 分あたりの合計接続数を超えていないか
    • このセッションが持つ接続 ID セットに接続 ID を追加し、セッション TTL を更新
    • このテナントの合計接続数をインクリメント
  6. メッセージは、API Gateway のルートに応じて、サイロまたはプールリソースの SQS FIFO キューを介して処理されます。SQS FIFO キューを使用しているのは、メッセージの順序を保証するためです。これは、メッセージが直接 Lambda 関数に送信された場合、最初のメッセージでコールドスタートが発生する可能性があるためです。これによって最初の処理が遅れ、後続のメッセージがウォームな高速に処理される Lambda 関数に割り当てられることで、異なる順序の返信が返されることになります。テナント ID、セッション ID、接続 ID、およびテナント設定は、メッセージメタデータとして各メッセージに追加されます。SQS FIFO キューの SQS メッセージグループ ID にはテナント ID とセッション ID の組み合わせを使用し、メッセージの順序を維持します。メッセージを受信するたびに DynamoDB セッション TTL を更新することで、セッションタイムアウトがリセットされ、アクティビティに応じて接続を長時間維持できます。
    • サイロベースのメッセージは、当該テナントに対応する専用の SQS FIFO キューによって処理されます。このキューには、テナント ID を使用した名前が付けられています。SQS FIFO キューからメッセージを読み取るための Lambda 関数もテナントごとに作成されています。
    • プールベースのメッセージは、単一の共有 SQS FIFO キューによって処理されます。この共有 SQS FIFO キューからメッセージを読み取るための Lambda 関数は 1 つで、全てのテナントで共有されます。
  7. 切断時に Lambda 関数は次の処理を行います。
    • セッションが持つ接続 ID セットから接続 ID を削除
    • テナントの合計接続数をデクリメント
  8. すべての接続が閉じられると、クライアントは API Gateway の HTTP エンドポイントに HTTP DELETE リクエストを送信してセッションを削除します。

WebSocket 接続とメッセージのシーケンス

テナントとセッションの情報が正しいことを確認するために、各接続を検証します。テナントまたはセッションが無効な場合、403 Forbidden のレスポンスコードが返されます。

図 2 – 無効なテナントまたはセッションによる接続は拒否され、403 Forbidden のレスポンスを受け取る

テナントとセッションが検証されると、$connect ルートの Lambda 関数 (図3 の Connect Route)によって接続が処理され、現在のテナントの接続数が検証されます。接続数が現在の制限を超えている場合は、429 のレスポンスコードがユーザーに返されます。

図 3 – ユーザー接続が接続レート制限に達し、429 Too Many Requests レスポンスを受け取る

テナントとセッションが検証され、接続が許可されると、メッセージが別の Lambda 関数によって処理されます。この Lambda 関数は、現在の期間におけるテナントとセッションの合計メッセージ数をインクリメントします。

合計メッセージ数がテナントまたはセッションの現在の制限を超えている場合、Too Many Requests のレスポンスメッセージが送信され、後続のメッセージはそれ以上処理されません。

図4 – ユーザー接続がメッセージのレート制限に達し、429 Too Many Requests レスポンスを受け取る。これにより、リソース使用量を下げるためそれ以降のメッセージ処理が停止する

テナントとセッションが有効で、接続およびメッセージが制限を超えていなければ、メッセージは正常に処理されます。メッセージは、ユーザーが接続を切断するまで処理され続けます。

図 5 – ユーザー接続が成功し、スロットリングせずにメッセージが処理される。

SQS FIFO キューと Lambda 関数のどちらを使うか

SQS FIFO キューが使用される主な理由は、チャットの会話でメッセージが正しい順序で処理されるようにするためです。

メッセージを処理するために Amazon API Gateway から直接 Lambda 関数を呼び出すこともできますが、この場合メッセージが順不同に処理される可能性があります。

これを回避するために、WebSocket エンドポイントは SQS FIFO キューにメッセージを送信するように設定されています。FIFO キューには次のような利点があります。

  • グループ ID によってメッセージをグループ化することで、ノイジーネイバーの問題を軽減します。これにより、処理が並列化され、メッセージフローがブロックされなくなります。例えば、テナント A の受信メッセージが急増しても、テナントレベルでグループ化と順序が確保されているため、テナント B の処理速度には影響がありません。
  • 処理が失敗した場合でも、リトライの中で順序は保証されます。グループ ID からメッセージを受信すると、処理中のメッセージを削除するか、可視性タイムアウトの期限が切れる場合を除き、同じグループ ID のメッセージはそれ以上処理されません。
  • Amazon API Gateway と Lambda 関数における競合状態を回避します。Lambda 関数のコールドスタートや、関数内のコードにサードパーティのサービスの呼び出しが含まれていると、メッセージが順不同に処理されることがあります。例えば、メッセージ A がコールドスタートする Lambda 関数インスタンスに割り当てられ、メッセージ B がウォームスタートする Lambda 関数インスタンスに割り当てられた場合、メッセージ B はメッセージ A より先に処理されます。この状態は望ましくありません。実行順序が保持されていても、外部依存関係が失敗してメッセージ A の処理をリトライしなければならない場合があります。カスタマーサービスとのやりとり (チャットでの会話) のコンテキストと整合性を保つために、メッセージの順序性は非常に重要です。

FIFO による順序保証が不要な場合は、Lambda 関数を直接呼び出す方が便利な場合があります。Lambda 関数を直接呼び出す場合は、プロビジョニング済み同時実行数を念頭に置いて、各テナントがそれぞれのティアレベルで許容できるレートでメッセージを処理できるようにしてください。Lambda 関数を直接実行する場合も SQS キューに送信する場合も、同様の考慮が必要です。

サイロ / プール / ブリッジモデル

このソリューションで使用されるサービスは、メッセージの処理方法に応じて複数の構成を取ることができます。サービスをサイロ、プール、ブリッジモデルのどれで構成するかは、テナントあたりの流量の増加、テナントティアモデルの作成、運用のオーバーヘッドおよびコストの削減など、システムのさまざまな側面に影響を与える可能性があります。

Pegasystems は、ティアごとの柔軟性を高め、より多くのキャパシティを必要とする顧客を専用のキューに分離することができるブリッジモデルを選択しました。

  • サイロモデルでは、テナントごとに作成した専用の SQS FIFO キューによってメッセージを処理します。各テナントのキューは 1 つ以上の専用の Lambda 関数によって処理されます。このモデルでは、テナントごとの流量を最も柔軟に制御できますが、運用上のオーバーヘッドとコストが増加する恐れがあります。SQS メッセージグループ ID に基づいて、複数の Lambda 関数を FIFO キューの処理に使用することもできますが、これはパフォーマンスの向上とともにコストの増加ももたらします。
  • プールモデルでは、すべてのテナントに対して単一の SQS FIFO キューを作成することによってメッセージを処理します。1 つ以上の Lambda 関数が、メタデータに含まれるテナント情報を使用してテナントの流量を制御しながらキュー内のメッセージを処理します。リソースを共有するため、この方法では、運用上のオーバーヘッドとコストを削減できます。1 つの大きな欠点としては、複数のテナントを処理するので 1 つの FIFO キューにおけるメッセージスループットなどの FIFO キューの制限 に達する可能性があることです。
  • ブリッジモデルのメッセージ処理は、サイロモデルとプールモデルの両方を組み合わせたものとなります。テナントのティアに応じて、1 つのキューが割り当てられるテナントもあれば、1つのキューを複数テナントで共有するものもあります。ブリッジモデルを使用すると、複数のティアをサポートすることができます。例えば、テナント数が少ないキュー、または多いキューを作成し、それぞれ異なる支払い体系を持たせることもできます。

AWS Lambda オーソライザーと接続ルートのパフォーマンス

紹介したアーキテクチャ ( 1 を参照) では、Amazon DynamoDB をデータベースとして活用し、各テナントの接続、セッション、メッセージレートを保存しています。

DynamoDB は、パフォーマンス、耐久性、サーバーレス、コストメトリクスを考慮して選定しました。耐久性は、システムがセッション情報を保持するために不可欠です。

システム運用という観点では、サーバーレスを使用することでメンテナンスが容易になります。また、DynamoDB は、アクティブな状態を保ったまま自動スケーリングさせることができます。ミリ秒の応答時間は、このユースケースでは許容範囲内です。

より低いレイテンシーが必要な場合は、Amazon DynamoDB Accelerator (DAX) をソリューションに追加して、サーバーレスのアプローチを維持したままパフォーマンスを向上させることもできます。

このシナリオでは、Amazon ElastiCache または Amazon MemoryDB for Redis も使用できます。レイテンシーや耐久性、コスト、運用管理などユースケースの要件に応じて選択するようにしてください。レイテンシーが重要な場合は、ミリ秒未満を提供する ElastiCache か、1 桁ミリ秒のレベルを提供する DynamoDB が候補になります。

コストの見積もりでは、1 秒あたりの接続数と、各読み取り/書き込みの合計バイト数を考慮する必要があります。

Amazon API Gateway の認証キャッシュは現在 WebSocket 接続では利用できないため、接続ごとにオーソライザーと $connect ルートが呼び出されることに注意してください。

データベース層へのリクエスト呼び出し回数を減らすには、AWS Lambda Extensionts によるデータキャッシュも検討してください。

まとめ

この記事では、Amazon API Gateway、AWS Lambda、Amazon SQS、および Amazon DynamoDB を使用してマルチテナントのメッセージングプラットフォームを構築し、WebSocket 接続とメッセージのレート制限を行う方法について解説しました。

ノイジーネイバーの懸念とメッセージの順序保証は、メッセージングシステムにとって重要ですが、このアーキテクチャを使用することで懸念を削減することができます。各テナントに最高のエクスペリエンスを提供すると同時に、コストの削減あるいはパフォーマンス向上の余地も残しておけるような設計を心がけましょう。


Pegasystems – AWS パートナースポットライト

Pegasystems は、オートメーション、エンゲージメント、ローコード開発を通じて、最も複雑なビジネス課題を単純化する AWS パートナーです。

Pegasystems へのお問い合わせ | パートナー概要 | AWS Marketplace

*すでにPegasystemsと連携していますか? パートナーを評価する

*AWS パートナーを評価するには、プロジェクトでパートナーと直接協力したことがあるお客様である必要があります。

翻訳はパートナーソリューションアーキテクトの櫻谷が担当しました。

原文はこちらです。