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

Alibaba Cloud Service Mesh:ASM での gRPC ベースのサービスのトレース

最終更新日:Jan 13, 2025

可観測性分析は、トレースマッピング、コール統計、トレーストポロジー、アプリケーション依存関係分析など、分散アプリケーション開発のための一連のツールを提供します。 サービスメッシュ(ASM)は、可観測性分析と統合されています。 このトピックでは、ヘッダーを使用して ASM で gRPC ベースのサービスをトレースする方法について説明します。

前提条件

サンプルプロジェクト

gRPC のサンプルプロジェクトの詳細については、hello-servicemesh-grpc をご覧ください。 このトピックのディレクトリは、hello-servicemesh-grpc のディレクトリです。

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

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

  • 基本的な方法

    • Java を使用して、gRPC サーバーでヘッダーを取得するための基本的な方法を実装します。

      interceptCall(ServerCall<ReqT, RespT> call,final Metadata m,ServerCallHandler<ReqT, RespT> h) メソッドを実装します ServerInterceptor 操作の。 次に、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> mCallOptions 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.value の形式で設定します。 list tuple を使用して、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 は、Metadata-Context Propagation を使用してヘッダーをトレースします。机制

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

ヘッダーを伝搬できるようになると、gRPC クライアントとサーバー間のリクエストメッセージとレスポンスメッセージをトレースできます。

ASM インスタンストポロジーのデプロイと検証

gRPC ベースのサービスに対して可観測性分析を有効にする前に、gRPC ベースのサービスが存在する AMS インスタンストポロジーをデプロイして検証する必要があります。 ASM インスタンストポロジーが期待どおりに動作することを確認してください。

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

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

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

次の図は、デプロイされた Service Mesh インスタンストポロジーを示しています。网络拓扑

トレースデータを表示する

  1. ASM トレースデータを可観測性分析に収集します。 詳細については、「ASM トレースデータを可観測性分析に収集する」をご参照ください。

  2. Managed Service for OpenTelemetry コンソールにログインします。 左側のナビゲーションペインで、[トレースエントリ] をクリックします。

  3. [トレースエントリ] ページで、目的のアプリケーションの [アプリケーショントポロジー] をクリックします。

    ローカルリクエスター - Ingressgateway - grpc-server - svc1 - grpc-server - svc2 - grpc-server - svc3 を含む、完全なトレースを確認できます。链路追踪

  4. [エンドツーエンド集計] ページで、[エンドツーエンド集計] タブをクリックして、集計されたトレースを表示します。

    全链路聚合

  5. [エンドツーエンド集計] タブで、[スパン名] 列のトレースをクリックして、トレースの詳細情報を表示します。

    调用链路