Go アプリケーションのプロファイリング
このページでは、プロファイリング データを収集し、そのデータを Google Cloud プロジェクトに送信するように Go アプリケーションを変更する方法について説明します。プロファイリングの全般的な情報については、プロファイリングのコンセプトをご覧ください。
Go のプロファイル タイプ:
- CPU 時間
- ヒープ
- 割り当てられたヒープ
- 競合(Go Mutex)
- スレッド(Go Goroutine)
サポートされている Go 言語バージョン:
- 特に明記されていない限り、正式に管理されているすべての Go リリース。詳細については、Go 言語のリリース ポリシーをご覧ください。
サポートされているプロファイリング エージェントのバージョン:
- エージェントの最新リリースがサポートされています。一般に、1 年を超える期間が経過したリリースはサポートされません。エージェントの最新リリース バージョンを使用することをおすすめします。
サポートされているオペレーティング システム:
- Linux。Go アプリケーションのプロファイリングは、標準 C ライブラリが
glibc
またはmusl
で実装されている Linux カーネルでサポートされています。Linux Alpine カーネルに固有の構成情報については、Linux Alpine で実行するをご覧ください。
サポートされる環境:
- Compute Engine
- Google Kubernetes Engine(GKE)
- App Engine フレキシブル環境
- App Engine スタンダード環境(Go 1.11 以降が必要)
- Google Cloud の外部(追加の構成要件については、Google Cloud の外部で実行されているアプリケーションのプロファイリングをご覧ください)。
Profiler API を有効にする
プロファイリング エージェントを使用する前に、基盤となる Profiler API が有効になっている必要があります。Google Cloud CLI または Google Cloud Console のいずれかを使用して、API のステータスを確認し、必要に応じて有効にできます。
gcloud CLI
ワークステーションに Google Cloud CLI がまだインストールされていない場合は、Google Cloud CLI のドキュメントをご覧ください。
次のコマンドを実行します。
gcloud services enable cloudprofiler.googleapis.com
詳細については、gcloud services
をご覧ください。
Google Cloud コンソール
-
Enable the required API.
[API が有効です] が表示されている場合、API はすでに有効になっています。そうでない場合は、[有効にする] ボタンをクリックします。
サービス アカウントに IAM ロールを付与する
Google Cloud リソースにアプリケーションをデプロイし、デフォルトのサービス アカウントを使用していて、そのサービス アカウントへのロール付与を変更していない場合は、このセクションをスキップできます。
次のいずれかを行う場合は、サービス アカウントに Cloud Profiler エージェント(roles/cloudprofiler.agent
)の IAM ロールを付与する必要があります。
- デフォルトのサービス アカウントを使用しているものの、ロール付与を変更している。
- ユーザーが作成したサービス アカウントを使用している。
- 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 を使用するには、アプリケーションにパッケージをインポートし、アプリケーションの早い段階で Profiler を初期化します。
MutexProfiling
構成オプションを true
に設定すると、ミューテックス競合プロファイリング(インターフェースでは「競合」)を有効にできます。
構成オプションを含む Profiler API の詳細については、公開 API のドキュメントをご覧ください。
Compute Engine
Compute Engine の場合、profiler.Config
で Service
にプロファイリング対象のサービスの名前を設定し、必要に応じて ServiceVersion
にサービスのバージョンを設定します。
ソースコードの依存関係を手動で取得する場合は、ビルド スクリプトまたは Dockerfile に以下を追加する必要があります。
go get cloud.google.com/go/profiler
GKE
GKE の場合は、profiler.Config
で Service
にプロファイリング対象のサービスの名前を設定し、必要に応じて ServiceVersion
にサービスのバージョンを設定します。
ソースコードの依存関係を手動で取得する場合は、ビルド スクリプトまたは Dockerfile に以下を追加する必要があります。
go get cloud.google.com/go/profiler
App Engine
App Engine フレキシブル環境と App Engine スタンダード環境の場合、コードの追加は Compute Engine と GKE の場合とほぼ同じです。例外が 1 つあります。App Engine 環境では、Service
パラメータと ServiceVersion
パラメータは環境から取得されるため、これらを指定する必要はありません。
アプリケーションをローカルで実行する場合は、ProjectID
(Google Cloud プロジェクトの ID)と Service
パラメータを profiler.Config
に設定します。これらのパラメータは、ローカル環境から取得されません。ServiceVersion
を設定する必要はありません。
App Engine スタンダード環境の場合は、Go 1.11 へのアプリの移行で、アプリケーションに必要な変更の詳細を確認してください。また、Google Cloud CLI バージョン 226.0.0 以降を使用する必要があります。Google Cloud CLI を更新するには、次のコマンドを実行します。
gcloud components update
アプリケーションを実行するには:
依存関係を更新します。
go get cloud.google.com/go/profiler
App Engine フレキシブル環境または App Engine スタンダード環境にアプリケーションをデプロイします。
gcloud app deploy [DEPLOYMENT]
DEPLOYMENT
は構成ファイルのパスです。たとえば、DEPLOYMENT
はmain/app.yaml
になります。- App Engine フレキシブル環境でのデプロイメントの詳細については、アプリケーションのテストとデプロイをご覧ください。
- App Engine スタンダード環境でのデプロイメントの詳細については、アプリケーションのテストとデプロイをご覧ください。
データの分析
Profiler が収集したデータを Profiler のインターフェースに表示し、分析できます。
Google Cloud コンソールで [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.0
、2.1.2
)。
エージェント ロギング
プロファイリング エージェントには、ログにデバッグ情報を出力する機能があります。デフォルトでは、エージェント ロギングは無効になっています。
エージェント ロギングを有効にするには、エージェントの起動時に DebugLogging
オプションを true
に設定します。
profiler.Start(profiler.Config{..., DebugLogging: true});
トラブルシューティング
このセクションでは、Go アプリケーションのプロファイリングに固有の問題について説明します。一般的な問題のヘルプについては、こちらのトラブルシューティングをご覧ください。
動作 | 原因 | 解決策 |
---|---|---|
-buildmode=c-archive を使用してビルドされたアプリケーションでは、CPU 時間プロファイルは収集されません。ヒープ、競合、スレッドのプロファイルが収集されます。GitHub の問題 |
デフォルトでは、-buildmode フラグが c-archive または c-shared の場合、Go アプリケーションに対して CPU プロファイリングが有効になっていません。 |
profiler.Start を呼び出す前にsignal.Notify(make( への呼び出しを追加します。GitHub の問題へのレスポンス。 |
Linux Alpine で実行する
Linux Alpine 用の Go プロファイリング エージェントは、Google Kubernetes Engine の構成でのみサポートされています。
認証エラー
Linux Alpine で Docker イメージ(golang:alpine
や alpine
など)を使用すると、次の認証エラーが表示されることがあります。
connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"
エラーの詳細を確認するには、エージェント ロギングを有効にする必要があります。 デフォルトでは、Go エージェントはログメッセージを出力しません。
上記のエラーは、Linux Alpine の Docker イメージに、デフォルトでインストールされているはずのルート SSL 証明書がないことを示しています。これらの証明書は、プロファイリング エージェントが Profiler API と通信するために必要になります。このエラーを解決するには、次の apk
コマンドを Dockerfile に追加します。
FROM alpine
...
RUN apk add --no-cache ca-certificates
その後、アプリケーションを再度ビルドし、デプロイする必要があります。