Node.js アプリケーションのプロファイリング

このページでは、プロファイリング データを収集し、そのデータを Google Cloud プロジェクトに送信するように Node.js アプリケーションを変更する方法について説明します。プロファイリングの全般的な情報については、プロファイリングのコンセプトをご覧ください。

Node.js のプロファイル タイプ:

  • ヒープ
  • 経過時間

サポートされる Node.js 言語バージョン:

  • Node.js 14 以降
  • Node.js リリース ポリシーについては、Release schedule をご覧ください。

サポートされているプロファイリング エージェントのバージョン:

  • エージェントの最新リリースがサポートされています。一般に、1 年を超える期間が経過したリリースはサポートされません。エージェントの最新リリース バージョンを使用することをおすすめします。

サポートされているオペレーティング システム:

  • Linux。Node.js アプリケーションのプロファイリングは、標準 C ライブラリが glibc または musl で実装されている Linux カーネルでサポートされています。Linux Alpine カーネルに固有の構成情報については、Linux Alpine で実行するをご覧ください。

サポートされる環境:

Profiler API を有効にする

プロファイリング エージェントを使用する前に、基盤となる Profiler API が有効になっている必要があります。Google Cloud CLI または Google Cloud Console のいずれかを使用して、API のステータスを確認し、必要に応じて有効にできます。

gcloud CLI

  1. ワークステーションに Google Cloud CLI がまだインストールされていない場合は、Google Cloud CLI のドキュメントをご覧ください。

  2. 次のコマンドを実行します。

    gcloud services enable cloudprofiler.googleapis.com
    

詳細については、gcloud services をご覧ください。

Google Cloud コンソール

  1. Enable the required API.

    Enable the API

  2. [API が有効です] が表示されている場合、API はすでに有効になっています。そうでない場合は、[有効にする] ボタンをクリックします。

サービス アカウントに IAM ロールを付与する

Google Cloud リソースにアプリケーションをデプロイし、デフォルトのサービス アカウントを使用していて、そのサービス アカウントへのロール付与を変更していない場合は、このセクションをスキップできます。

次のいずれかを行う場合は、サービス アカウントに Cloud Profiler エージェント(roles/cloudprofiler.agentの IAM ロールを付与する必要があります。

  1. デフォルトのサービス アカウントを使用しているものの、ロール付与を変更している。
  2. ユーザーが作成したサービス アカウントを使用している。
  3. Workload Identity を使用している場合は、Kubernetes サービス アカウントに Cloud Profiler エージェントのロールを付与します。

サービス アカウントに IAM ロールを付与するには、Google Cloud コンソールまたは Google Cloud CLI を使用します。たとえば、gcloud projects add-iam-policy-binding コマンドを使用できます。

gcloud projects add-iam-policy-binding GCP_PROJECT_ID \
    --member serviceAccount:MY_SVC_ACCT_ID@GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/cloudprofiler.agent

上のコマンドを使用する前に、次のように置き換えます。

  • GCP_PROJECT_ID: プロジェクト ID。
  • MY_SVC_ACCT_ID: サービス アカウントの名前。

詳細については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

Cloud Profiler の使用

サポートされているすべての環境で Profiler を使用するには、パッケージ @google-cloud/profiler をインストールし、アプリケーションに require ステートメントを追加してから、通常の方法でアプリケーションをデプロイします。

@google-cloud/profiler をインストールする前に

パッケージ @google-cloud/profiler は組み込みモジュールに依存しています。Node 14 と 16 の場合、この組み込みモジュールのビルド済みバイナリは、Linux と Alpine Linux で使用できます。追加の依存関係は必要ありません。@google-cloud/profiler は、node-pre-gyp を使用してインストールするビルド済みバイナリを決定します。

ビルド済みバイナリがない他の環境で @google-cloud/profiler を使用する場合は、モジュール node-gyp を使用してバイナリをビルドします。node-gyp でバイナリをビルドするために必要な依存関係については、node-gyp のインストールに関するドキュメントをご覧ください。

インストール

Cloud Profiler の最新バージョンをインストールするには、次の操作を行います。

    npm install --save @google-cloud/profiler

Trace エージェントも使用している場合は、アプリケーションを変更するときに、Trace エージェント パッケージ(@google-cloud/trace-agent)の後に Profiler パッケージをインポートします。

Compute Engine

Compute Engine の場合は、次の操作を行います。

  1. Cloud Profiler の最新バージョンをインストールします。

    npm install --save @google-cloud/profiler
    
  2. アプリケーションの require コードを変更して、serviceContext オブジェクトを作成します。このオブジェクトにより、プロファイリングされるサービスの名前を service に割り当てます。必要に応じて、プロファイリングするサービスのバージョンを version に割り当てることができます。これらの構成オプションの詳細については、サービス名とバージョンの引数をご覧ください。

    require('@google-cloud/profiler').start({
      serviceContext: {
        service: 'your-service',
        version: '1.0.0',
      },
    });

GKE

GKE の場合は、次の操作を行います。

  1. Dockerfile を変更して Profiler パッケージをインストールします。

    FROM node:10
    ...
    RUN npm install @google-cloud/profiler
    
  2. アプリケーションの require コードを変更して、serviceContext オブジェクトを作成します。このオブジェクトにより、プロファイリングされるサービスの名前を service に割り当てます。必要に応じて、プロファイリングするサービスのバージョンを version に割り当てることができます。これらの構成オプションの詳細については、サービス名とバージョンの引数をご覧ください。

    require('@google-cloud/profiler').start({
      serviceContext: {
        service: 'your-service',
        version: '1.0.0',
      },
    });

App Engine

App Engine フレキシブル環境と App Engine スタンダード環境の場合、require コードは次のようになります。

require('@google-cloud/profiler').start();

App Engine では、service パラメータと version パラメータは環境から取得されるため、これらを指定する必要はありません。したがって、serviceContext オブジェクトを作成する必要はありません。

データの分析

Profiler が収集したデータを Profiler のインターフェースに表示し、分析できます。

Google Cloud コンソールで [Profiler] ページに移動します。

[Profiler] に移動

このページは、検索バーを使用して見つけることもできます。

サービス名とバージョンの引数

Profiler エージェントを読み込むときに、service-name 引数とオプションの service-version 引数を指定して構成します。

Profiler は、サービス名で指定されたサービスのすべてのレプリカからプロファイリング データを収集します。Profiler サービスは、サービス バージョンとゾーンの組み合わせに対して、1 つのサービス名について平均で 1 分あたり 1 個のプロファイルを作成します。

たとえば、1 つのサービスの 2 つのバージョンが 3 つのゾーンのレプリカで実行されている場合、Profiler はそのサービスについて 1 分あたり平均で 6 個のプロファイルを作成します。

レプリカで異なるサービス名を使用している場合、サービスが必要以上にプロファイリングされるため、オーバーヘッドが大きくなります。

サービス名を選択する場合は、次の点に注意してください。

  • アプリケーション アーキテクチャでサービスを明確に識別できる名前を選択してください。1 つのサービスまたはアプリケーションしか実行していない場合、どのようなサービス名を選択するかはさほど問題になりません。しかし、アプリケーションが一連のマイクロサービスとして実行されている場合は、名前の選択が重要になります。

  • service-name 文字列で、プロセス ID などのプロセス固有の値を使用しないでください。

  • service-name 文字列は次の正規表現と一致する必要があります。

    ^[a-z0-9]([-a-z0-9_.]{0,253}[a-z0-9])?$

サービス名として imageproc-service のような静的な文字列を使用することをおすすめします。

サービス バージョンは省略可能です。サービス バージョンを指定すると、複数のインスタンスからプロファイリング情報が集約され、バージョンごとに表示されます。これは、複数のバージョンがデプロイされているときの識別に役立ちます。Profiler UI では、データをサービス バージョンでフィルタできます。これにより、コードの新旧バージョンのパフォーマンスを比較できます。

service-version 引数には、自由形式の文字列を指定できますが、通常は、バージョン番号のような値を使用します(例: 1.0.02.1.2)。

エージェント ロギング

プロファイリング エージェントには、ロギング情報を出力する機能があります。ロギングを有効にするには、エージェントの起動時に logLevel オプションを設定します。サポートされている logLevel 値は次の通りです。

  • 0: すべてのエージェント ロギングを無効にします。
  • 1: エラーロギングを有効にします。
  • 2: 警告ロギングを有効にします(デフォルト)。
  • 3: 情報ロギングを有効にします。
  • 4: デバッグ ロギングを有効にします。

サービス コンテキストを提供する同じオブジェクトに logLevel 値を設定します。

require('@google-cloud/profiler').start({
    serviceContext: { ... }
    logLevel:       3
});

Linux Alpine で実行する

Linux Alpine 用の Node.js プロファイリング エージェントは、Google Kubernetes Engine の構成でのみサポートされています。

ビルドエラー

npm install を実行した際に、次のエラーでビルドが失敗した場合、Dockerfile にビルドの依存関係がありません。

ERR! stack Error: not found: make

この問題を解決するには、Dockerfile のビルドステージに次のステートメントを追加します。

RUN apk add python3 g++ make

認証エラー

Linux Alpine で Docker イメージ(golang:alpinealpine など)を使用すると、次の認証エラーが表示されることがあります。

connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"

エラーの詳細を確認するには、エージェント ロギングを有効にする必要があります。

上記のエラーは、Linux Alpine の Docker イメージに、デフォルトでインストールされているはずのルート SSL 証明書がないことを示しています。これらの証明書は、プロファイリング エージェントが Profiler API と通信するために必要になります。このエラーを解決するには、次の apk コマンドを Dockerfile に追加します。

FROM alpine
...
RUN apk add --no-cache ca-certificates

その後、アプリケーションを再度ビルドし、デプロイする必要があります。

既知の問題

Node.js のプロファイリング エージェントが原因でプログラムが通常どおり終了しません。プログラムのすべてのタスクが完了してからプログラムが終了するまでに、最大で 1 時間ほどかかります。Ctrl-C などを使用して SIGINT を発行した場合は、プロセスが正常に終了します。

次のステップ