すべてのプロダクト
Search
ドキュメントセンター

:gRPC ベースのアプリケーションのトラフィックをリダイレクトする

最終更新日:Nov 06, 2025

Service Mesh (ASM) では、ヘッダーのキーと値に一致条件を設定できます。これにより、ASM はリクエストヘッダーに基づいてトラフィックを動的にリダイレクトできます。このトピックでは、ヘッダーに基づいて ASM のアプリケーションのトラフィックをリダイレクトする方法について説明します。

gRPC サーバーとクライアントでヘッダーを取得する

GRPC サーバーでヘッダーを取得する

  • 基本的なメソッド

    • Java を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。

      ServerInterceptor 操作の interceptCall(ServerCall<ReqT, RespT> call,final Metadata m,ServerCallHandler<ReqT, RespT> h) メソッドを実装します。次に、String v = m.get(k) コマンドを実行して、サーバーでヘッダーを取得します。get() メソッドの入力パラメーターのタイプは Metadata.Key<String> です。

    • Go を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。

      metadata.FromIncomingContext(ctx)(md MD, ok bool) メソッドを実装します。MD のフォーマットは map[string][]string です。

    • Node.js を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。

      call.metadata.getmap() メソッドを実装します。戻り値のタイプは [key: string]: MetadataValue です。MetadataValue のタイプは string/Buffer です。

    • Python を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。

      context.invocation_metadata() メソッドを実装します。戻り値は ('k','v') のフォーマットの 2 タプル配列です。キーと値のペアは m.key, m.value から取得できます。

  • 単項 RPC

    • Java を使用して、サーバーでヘッダーを取得する単項リモートプロシージャコール (RPC) メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。

      メソッドで metadata.FromIncomingContext(ctx) を呼び出します。ctx パラメーターの値は、Talk メソッドの入力パラメーターから取得されます。

    • Node.js を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。

      メソッドで call.metadata.getMap() を呼び出します。

    • Python を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。

      メソッドで context.invocation_metadata() を呼び出します。

  • サーバー ストリーミング RPC

    • Java を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。

      メソッドで metadata.FromIncomingContext(ctx) を呼び出します。stream.Context() メソッドを呼び出して、TalkOneAnswerMore メソッドの入力パラメーター stream から ctx パラメーターの値を取得できます。

    • Node.js を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。

      メソッドで call.metadata.getMap() を呼び出します。

    • Python を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。

      メソッドで context.invocation_metadata() を呼び出します。

  • クライアント ストリーミング RPC

    • Java を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。

      メソッドで metadata.FromIncomingContext(ctx) を呼び出します。stream.Context() メソッドを呼び出して、TalkMoreAnswerOne メソッドの入力パラメーター stream から ctx パラメーターの値を取得できます。

    • Node.js を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。

      メソッドで call.metadata.getMap() を呼び出します。

    • Python を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。

      メソッドで context.invocation_metadata() を呼び出します。

  • 双方向ストリーミング RPC

    • Java を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。

      メソッドで metadata.FromIncomingContext(ctx) を呼び出します。stream.Context() メソッドを呼び出して、TalkBidirectional メソッドの入力パラメーター stream から ctx パラメーターの値を取得できます。

    • Node.js を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。

      メソッドで call.metadata.getMap() を呼び出します。

    • Python を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。

      メソッドで context.invocation_metadata() を呼び出します。

クライアントからヘッダーを送信する

  • 基本的なメソッド

    • Java を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。

      ClientInterceptor 操作の interceptCall(MethodDescriptor<ReqT, RespT> m, CallOptions o, Channel c) メソッドを実装します。ClientCall<ReqT, RespT> タイプの start((Listener<RespT> l, Metadata h)) メソッドを実装します。次に、h.put(k, v) を実行して、クライアントでヘッダーを送信します。put の入力パラメーター k のタイプは Metadata.Key<String> で、入力パラメーター v のタイプは String です。

    • Go を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。

      metadata.AppendToOutgoingContext(ctx,kv ...) context.Context

    • Node.js を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。

      metadata=call.metadata.getMap()metadata.add(key, headers[key])

    • Python を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。

      metadata_dict = {} コマンドで変数を次のフォーマットで設定します: metadata_dict[c.key] = c.valuelist(metadata_dict.items()) を使用して、metadata_dict 配列のデータのタイプを list tuple に変換します。

  • 単項 RPC

    • Java を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、クライアントでヘッダーを送信する単項 RPC メソッドを実装します。

      メソッドで metadata.AppendToOutgoingContext(ctx,kv) を呼び出します。

    • Node.js を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

    • Python を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

  • サーバー ストリーミング RPC

    • Java を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。

      メソッドで metadata.AppendToOutgoingContext(ctx,kv) を呼び出します。

    • Node.js を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

    • Python を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

  • クライアント ストリーミング RPC

    • Java を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。

      メソッドで metadata.AppendToOutgoingContext(ctx,kv) を呼び出します。

    • Node.js を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

    • Python を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

  • 双方向ストリーミング RPC

    • Java を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。

      ヘッダーはインターセプトされます。

    • Go を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。

      メソッドで metadata.AppendToOutgoingContext(ctx,kv) を呼び出します。

    • Node.js を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

    • Python を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。

      基本的なメソッドを呼び出します。

プロパガンダヘッダー

トレース分析では、トレースの完全な情報を取得するために、アップストリームリンクのメタデータをダウンストリームに渡す必要があります。したがって、サーバーで取得されたトレース関連のヘッダー情報は、ダウンストリームにリクエストを送信するクライアントに渡す必要があります。

Go、Node.js、および Python を使用して実装される通信モデルの操作は、ヘッダーを受信できます。したがって、4 つの通信モデルの操作を使用して、次の 3 つのアクションを順番に実装できます。まず、サーバーがヘッダーを読み取ります。次に、サーバーがヘッダーを渡します。最後に、クライアントがヘッダーを送信します。

Java を使用して実装された通信モデルの操作は、順序付けられたプロセスでヘッダーを伝播するために使用することはできません。これは、Java が 2 つのインターセプタを使用してヘッダーを読み書きするためです。読み取りインターセプタのみがトレースの一意の ID を取得します。さらに、gRPC サービスは同時にリクエストを受信および送信する場合があります。その結果、2 つのインターセプタは、トレースを表示するための最も直感的な方法であるキャッシングを使用して接続することはできません。

Java は、メタデータコンテキスト伝播を使用してヘッダーをトレースします。Mechanism

サーバーインターセプタがヘッダーを読み取るとき、headersctx.withValue(key, metadata) を使用してコンテキストに書き込まれます。key パラメーターのタイプは Context.Key<String> です。次に、クライアントインターセプタは key.get() を使用してコンテキストから headers を読み取ります。デフォルトでは、get メソッドは Context.current() を使用します。これにより、ヘッダーが読み書きされるときに同じコンテキストが使用されることが保証されます。

ヘッダーが伝播できる場合、gRPC クライアントとサーバー間のリクエストと応答メッセージをトレースできます。

ASM インスタンスのトポロジーをデプロイして検証する

トラフィックをリダイレクトする前に、アプリケーションが存在する ASM インスタンスのトポロジーをデプロイして検証する必要があります。ASM インスタンスのトポロジーが期待どおりに機能することを確認してください。

サンプルプロジェクトの tracing フォルダには、Java、Go、Node.js、および Python のデプロイメントスクリプトが含まれています。この例では、Go デプロイメントスクリプトを使用して、ASM インスタンスのトポロジーをデプロイおよび検証します。

cd go
# ASM インスタンスのトポロジーをデプロイします。
sh apply.sh
# ASM インスタンスのトポロジーを検証します。
sh test.sh

例外が発生しない場合、ASM インスタンスのトポロジーは期待どおりに機能します。

次の図は、デプロイされた ASM インスタンスのトポロジーを示しています。Network topology

トラフィックのリダイレクト

ASM で仮想サービスを作成して、ヘッダーのキーと値に一致条件を設定できます。これにより、ASM はリクエストヘッダーに基づいてトラフィックを動的にリダイレクトできます。さらに、gRPC バージョンと gRPC API 操作に基づいて、アプリケーションのトラフィックをきめ細かくシェーピングできます。詳細については、「gRPC サーバーへのトラフィックのシェーピング」をご参照ください。次の例では、ヘッダーに server-version=go が含まれるすべてのリクエストを Go ベースの gRPC サーバーに転送する仮想サービスを作成する方法を示します。

  1. ASM コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。

  3. [メッシュ管理] ページで、設定する ASM インスタンスを見つけます。ASM インスタンスの名前をクリックするか、[アクション] 列の [管理] をクリックします。

  4. ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウから [トラフィック管理センター] > [VirtualService] を選択します。表示されたページで、[YAML から作成] をクリックします。

  5. [作成] ページで、必要に応じて名前空間を選択し、次の内容をコードエディタにコピーしてから、[作成] をクリックします。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      namespace: grpc-best
      name: grpc-server-vs
    spec:
      hosts:
        - "*"
      gateways:
        - grpc-gateway
      http:
        - match:
          - headers:
              server-version:
                exact: go
          route:
            - destination:
                host: grpc-server-svc
                subset: v2
              weight: 100