Function Compute は、同じ SessionId を持つ MCP Client リクエストに対してシステムレベルのアフィニティを提供します。MCP Client が最初の Server-Sent Events(SSE)リクエストを開始すると、システムは最初の event: endpoint イベントをインターセプトし、データから SessionId を解析し、SessionId をインスタンスにバインドします。同じ SessionId を持つ後続のリクエストは、アフィニティを確保するために、バインドされたインスタンスにルーティングされます。
プロトコル分析
Server-Sent Events(SSE)は、サーバーがリアルタイムのイベントまたはデータ更新をクライアントにプッシュできる HTTP ベースのテクノロジーです。サーバーはサブスクリプションリクエストを受信した後、接続を開いたままにし、HTTP ストリームを介してイベントをクライアントにプッシュします。各イベントには、次のフィールドが含まれています。
event: イベントフィールドのイベントタイプを指定します。
data: データフィールドの実際のコンテンツを送信します。
id (オプション): イベントを一意に識別します。
retry (オプション): 切断後の再接続間隔を retry フィールドに指定します。
MCP は、SSE プロトコルに基づいて、クライアントとサーバー間のリクエストインタラクションとアフィニティルーティングポリシーを実装します。MCP クライアントが最初の SSE リクエストを送信すると、MCP サービスは event: endpoint イベントの data フィールドに sessionId を配置し、クライアントに返します。後続のクライアントリクエストは、MCP サービスがそれらを識別できるように、この sessionId を保持する必要があります。
次の時系列グラフは、典型的な MCP SSE リクエストを示しています。
クライアントは GET リクエストを開始して、永続的な SSE 接続を確立します。(Connection 1)
サーバーは
event: endpointイベントで応答します。このイベントには、data フィールドに sessionId が含まれています。(Connection 1)クライアントは手順 2 の sessionId を使用して、最初の HTTP POST リクエストを開始します。(Connection 2)
サーバーは 202 Accepted で応答しますが、コンテンツはありません。(Connection 2)
サーバーは手順 3 のリクエストの実際のメッセージを返します。(Connection 1)
クライアントは手順 2 の sessionId を使用して、確認として
initializedを含む HTTP POST リクエストを開始します。(Connection 3)サーバーは 202 Accepted で応答しますが、コンテンツはありません。(Connection 3)
クライアントは手順 2 の sessionId を使用して、
ツールを一覧表示するための HTTP POST リクエストを開始します。(Connection 4)サーバーは 202 Accepted で応答しますが、コンテンツはありません。(Connection 4)
サーバーは手順 8 のリクエストの実際のメッセージ(ツールのリスト)を返します。(Connection 1)
クライアントは手順 2 の sessionId を使用して、
ツールを呼び出すための HTTP POST リクエストを開始します。(Connection 5)サーバーは 202 Accepted で応答しますが、コンテンツはありません。(Connection 5)
サーバーは手順 11 のリクエストの実際のメッセージ(ツール呼び出しの結果)を返します。(Connection 1)
実装の原則
セッション ID の生成とアフィニティ実装メカニズム
サーバーレスサービスとして、Function Compute は、柔軟なスケジューリング、コンピューティングホスティング、および運用と保守(O&M)不要の機能を提供します。Function Compute のコアコンポーネントは、次の 3 つの部分に抽象化できます。
ゲートウェイ: ゲートウェイ層はユーザートラフィックのエントリポイントであり、ユーザーリクエストの受信、認証、速度制限などの機能を担当します。
スケジューラ: スケジューリングエンジン層は、ユーザーリクエストを適切なノードとインスタンスにスケジューリングする役割を担います。
インスタンス: リソース層は、関数の実行環境です。
お客様が Function Compute で MCP サービスをホストし、MCP Client を介してリクエストを開始する場合、ユーザーリクエストは次の 2 つのカテゴリに分類できます。
SSE リクエスト
メッセージリクエスト
SSE リクエスト (セッションの初期化)
クライアントが最初の SSE リクエストを開始し、それが Function Compute ゲートウェイノードにルーティングされます。ゲートウェイノードで権限検証に合格すると、リクエストはスケジューラモジュールに転送されます。
スケジューラモジュールは、特定の識別子に基づいてリクエストタイプを SSE として識別し、リクエストを使用可能なインスタンスにスケジューリングします。
リクエストがインスタンスにバインドされると、インスタンスはユーザーコードを開始します。
ユーザーコードが開始されると、
event: endpointイベントの data フィールドに sessionId が配置され、最初のデータパケットが返されます。レスポンスがゲートウェイ層を通過すると、ゲートウェイ層は SSE リクエストの最初のレスポンスパケットをインターセプトし、SessionID を解析し、SessionID とインスタンス間のマッピングを DB に永続化します。
メッセージリクエスト (リクエスト処理)
クライアントが SSE リクエストを完了した後、複数のメッセージリクエストを開始します。Function Compute ゲートウェイノードはステートレスであるため、メッセージリクエストは複数のゲートウェイノードに分散されます。
ゲートウェイがメッセージリクエストを受信すると、キャッシュでメッセージリクエストの SessionID のアフィニティ情報を確認します。キャッシュにレコードが見つからない場合は、DB からオリジンフェッチを実行して関連データを取得します。
ゲートウェイは、キャッシュまたは DB から SessionID とインスタンスのバインディング関係を取得した後、関連情報を含むリクエストをスケジューラモジュールに転送します。
スケジューラモジュールは、特定の識別子に基づいてリクエストタイプをメッセージとして識別し、リクエスト内のインスタンス情報を解析し、リクエストを特定のインスタンスにスケジューリングします。
リクエストがインスタンスにバインドされると、MCP サーバーはリクエストを検証します。検証に成功すると、202 Accepted が返され、リクエストが受信されたことがクライアントに通知されます。実際のデータは、SSE リクエストによって確立された接続を介して返されます。
セッションの同時実行管理
MCP SSE セッションリソース要件モデルでは、単一のセッションライフサイクルには 2 種類の同時実行要件があります。
1 つの永続的な SSE 接続。1 つの同時実行クォータを占有します。
N(N >= 1)個のメッセージリクエスト。N 個の同時実行クォータを占有します。
ビジネスシナリオの要件に基づいて、適切な制限を設定する必要があります。
非アフィニティモードのシナリオでは、必要に応じてインスタンスごとの同時実行数を調整できます。
アフィニティモードでは、インスタンスごとの同時セッションの最大数のみが制限されます。単一インスタンス上のすべてのセッションの同時リクエストの最大数は 200 です。
同時実行パラメータタイプ | 意味 | 調整可能 | 制限 | 消費ルール | 同時実行解放メカニズム |
インスタンスごとの最大同時実行数 | 単一インスタンスが同時に処理できる同時リクエストの最大数。同時実行制限を超えるリクエストは、他のインスタンスにルーティングされるか、速度制限されます。 | 調整不可 | 200 | 各リクエスト (SSE/メッセージ) は 1 つの同時実行ユニットを占有します。 | リクエストが処理された後、非同期的に解放されます。 |
インスタンスごとの同時セッション数 | 単一インスタンスが同時に処理できるセッションの最大数。複数のセッションからのリクエストは、200 の同時実行数を共有します。 | 調整可能 | [1, 200] | 各 SSE 接続は 1 つのセッションを占有します。 | SSE 接続が切断された直後に解放されます。 |
セッションアフィニティの予期される動作 (インスタンススケジューリングルール)
シナリオ 1: セッションとインスタンスのバインディングルール、およびセッションによってトリガーされるインスタンススケールアウトメカニズム
Function Compute は、ポリシーを使用してインスタンスごとの同時セッション数を管理します。このポリシーでは、各インスタンスの最大セッション数が n に制限されます。プロセスは次のとおりです。
関数が 2 つのセッションをバインドするように設定されているとします。Client1 が SSE リクエストを開始すると、リクエストは Instance1 に割り当てられ、1 つのセッションの同時実行数が使用されます。
Client2 が SSE リクエストを開始すると、スケジューラは Instance1 に使用可能なセッションが 1 つあると判断し、リクエストを Instance1 にバインドします。
Client3 が SSE リクエストを開始すると、スケジューラは Instance1 の 2 つの同時セッションが使用されていると判断します。したがって、スケジューラはリクエストを新しいインスタンス Instance2 にスケジューリングし、インスタンスバインディングを完了します。
シナリオ 2: 単一インスタンスを共有する複数のセッションのリソース速度制限メカニズム
関数が 2 つの同時セッションをバインドするように設定されているとします。Client1 が SSE リクエストを開始すると、Instance1 が割り当てられます。インスタンスは
1 つの同時セッション + 1 つのリクエストの同時実行数を消費します。Client2 が SSE リクエストを開始すると、スケジューラは Instance1 に使用可能な同時セッションが 1 つあると判断し、リクエストを Instance1 にバインドします。この時点で、インスタンスは
2 つの同時セッション + 2 つのリクエストの同時実行数を消費します。Client1 と Client2 は同時に 198 件のメッセージリクエストを送信します。この時点で、インスタンスは
2 つの同時セッション + 200 件のリクエストの同時実行数を消費します。199 番目のメッセージリクエストが開始されると、単一インスタンスのリクエスト同時実行制限 200 に達し、リクエストは 429 エラーで速度制限されます。
スムーズな関数更新
MCP シナリオでは、データリクエストはリクエストレベルのステートレスからセッションレベルのステートフルに変わります。関数が更新された後、既存のセッションに関連付けられているリクエストが新しいインスタンスにルーティングされると、新しいインスタンスは SessionID を認識できず、エラーを返します。この問題を解決するために、Function Compute は、グレースフルアップデート機能をステートレスリクエストレベルからステートフルセッションレベルにアップグレードします。ユーザーが関数を更新した後、既存のセッションに関連付けられているリクエストは引き続き古いインスタンスにルーティングされ、新しいセッションリクエストは新しいインスタンスにルーティングされます。このプロセスにより、MCP アフィニティシナリオでのアップグレード要件がスムーズに実装されます。