このトピックでは、Function ComputeのManaged Service for OpenTelemetryの背景、シナリオ、およびコア機能について説明します。 このトピックでは、サンプリングルールを設定し、OpenTelemetryのManaged Serviceを有効にする方法についても説明します。
背景情報
Managed Service for OpenTelemetryはOpenTracing標準を採用しており、オープンソースコミュニティと互換性があります。 Managed Service for OpenTelemetryは、分散アプリケーションの開発者にさまざまな機能を提供します。 たとえば、開発者は分散トレースのクエリと診断、分散トポロジの動的な検出、アプリケーションのパフォーマンスのリアルタイムな要約を行うことができます。
Function Computeは、OpenTelemetryのマネージドサービスと統合されています。 Jaegerを使用してトレース情報をアップロードし、関数の呼び出しを追跡できます。 Managed Service for OpenTelemetryは、サーバーレスアーキテクチャのパフォーマンスボトルネックの分析と診断に役立ちます。 これにより、サーバーレスシナリオでの開発と診断の効率が向上します。
シナリオ
Function ComputeのサービスにManaged Service for OpenTelemetryを設定した後、Function Computeでリクエストの実行時間を記録できます。 関数のコールドスタート時間を表示し、関数の実行時間を記録することもできます。 Managed Service for OpenTelemetryは、次の問題のトラブルシューティングに役立ちます。
関数の各実行がタイムアウトした場合に、関数のパフォーマンスのボトルネックを特定します。
関数の実行時間が短い場合、エンドツーエンドのレイテンシが長い原因を特定します。
リクエストに分散システム内の複数のクラウドサービスが含まれる場合、関数のパフォーマンスのボトルネックを分析して診断します。
コア機能
Function ComputeのOpenTelemetry用マネージドサービスは、トレース全体を接続します。 OpenTelemetryのマネージドサービスは、次のコア機能を提供します。
Function Computeの主要なステップに費やされた時間を自動的に記録します。 詳細については、「Function Computeのキーステップに費やされた時間を自動的に記録する」をご参照ください。
上流サービスに接続します。 リクエストヘッダーにSpanContextが含まれている場合、Function ComputeはSpanContextに基づいて子スパンを作成します。 詳細については、「アップストリームサービスへの接続」をご参照ください。
下流サービスに接続します。 Function Computeは、SpanContextを関数コンテキストにインポートして、関数の内部トレースを追跡するのに役立ちます。 詳細については、「ダウンストリームサービスへの接続」をご参照ください。
アプリケーショントポロジを表示できます。
無効なAPI操作の実行を表示し、エラーの原因を特定できます。
Function Computeの主要なステップに費やされた時間を自動的に記録します。
次の図は、サービスのManaged Service for OpenTelemetryを有効にした後に表示できる既定のトレースを示しています。
次の項目は、スパン名を表します。
InvokeFunction: Function Computeでの現在のリクエストの合計実行時間。
ColdStart: 関数のシステムのコールドスタート時間。 コールドスタートは、関数を呼び出すたびに発生するわけではありません。 コールドスタートは、実行環境に再申請した場合にのみ発生します。
PrepareCode: 関数のコードまたはカスタムイメージをダウンロードするのにかかる時間。 PrepareCodeスパンで示される時間が長すぎる場合は、コードパッケージを単純化して、コードの準備にかかる時間を短縮します。
RuntimeInitialization: 実行環境の開始にかかる時間。インスタンスの開始にかかる時間と、インスタンスのヘルスチェックの実行にかかる時間を含みます。 カスタムランタイムとカスタムイメージの場合、RuntimeInitializationスパンで示される時間が長すぎる場合は、対応するHTTPサーバーとイメージの起動動作を確認します。
Initializer: 初期化子関数の実行にかかる時間。 初期化子関数は、コンテナでコールドスタートが発生した場合にのみ実行されます。
Invocation: 関数の実行にかかる時間。 関数で呼び出しのコンテキストを確認して、呼び出し時間を取得できます。
function Computeによって生成される関数の名前は、FC:ServiceName/FunctionName
の形式です。
リクエストにコールドスタートが発生しない場合、トレースにはコールドスタート期間とイニシャライザー期間は含まれません。 トレースを次の図に示します。
上流サービスへの接続
サービスに対してManaged Service for OpenTelemetryを有効にすると、リクエストヘッダーにSpanContextが含まれている場合、Function ComputeはSpanContextに基づいて子スパンを作成します。
Function Computeは、次のSpanContextヘッダーを識別します。
x-fc-tracing-opentracing-span-context
: SpanContextを送信します。x-fc-tracing-opentracing-span-context-baggage-
: クロスコンテキストの手荷物を送信します。複数の手荷物アイテムを送信する場合は、
x-fc-tracing-opentracing-span-context-baggage-key1: val1
やtracing-opentracing-span-context-baggage-key2: val2
などの複数のヘッダーを送信する必要があります。
SpanContextは、関数が呼び出されたときにSpanContextヘッダーを追加することで挿入できます。
Node.jsは次の例で使用されます。
'use strict';
const FCClient = require('@alicloud/fc2');
/*
The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using the AccessKey pair to perform operations is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M.
We recommend that you do not save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources under your account may be compromised.
In this example, the AccessKey pair is saved to the environment variables for authentication.
Configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables in your local environment before you run the sample code.
The ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are automatically configured after you configure the execution permissions in the runtime of Function Compute.
*/
var client = new FCClient('<account id>', {
accessKeyID: process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'],
accessKeySecret: process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'],
region: 'cn-shanghai',
});
var serviceName = '<service name>';
var funcName = '<function name>';
async function test() {
try {
// Inject the SpanContext header information.
var headers = {
'x-fc-tracing-opentracing-span-context': '124ed43254b54966:124ed43254b5****:0:1',
'x-fc-tracing-opentracing-span-context-baggage-key': 'val'
};
var resp = await client.invokeFunction(serviceName, functionName, 'event', headers = headers);
} catch (err) {
console.error(err);
}
}
下流サービスへの接続
Function Computeは、SpanContextを関数にインポートして、関数の内部トレースを追跡するのに役立ちます。
組み込みランタイムでは、SpanContextは
context.tracing
を使用して取得できます。カスタムランタイムまたはカスタムコンテナでは、Function ComputeのSpanContextをリクエストヘッダーから取得できます。
x-fc-tracing-opentracing-span-context
: Function ComputeのInvokeFunctionのSpanContext。 スパンは、関数内のSpanContextに基づいて作成されます。x-fc-tracing-opentracing-span-baggages
: Base64-encodedのクロスコンテキスト手荷物。x-fc-tracing-jaeger-endpoint
: Jaegerサーバーのエンドポイント。 関数内のスパンをこのエンドポイントに直接アップロードできます。
たとえば、context.tracing
の構造は次のとおりです。
exports.handler = (event, context, callback) => {
var params = {
openTracingSpanContext: context.tracing.openTracingSpanContext,
openTracingSpanBaggages:context.tracing.openTracingSpanBaggages,
// jaegerEndpoint is confidential, do not print it out easily
// jaegerEndpoint:context.tracing.jaegerEndpoint
}
console.log('tracing params',params)
callback(null,'success');
}
次のコードは、関数からSpanContextを取得する方法の例を示しています。
Node.js:
exports.handler = (event, context, callback) => { var params = { openTracingSpanContext: context.tracing.openTracingSpanContext, openTracingSpanBaggages:context.tracing.openTracingSpanBaggages, // jaegerEndpoint is confidential, do not print it out easily // jaegerEndpoint:context.tracing.jaegerEndpoint } console.log('tracing params',params) callback(null,'success'); }
PHP:
function handler($event, $ctx) { $logger = $GLOBALS['fcLogger']; $openTracingSpanContext = $ctx['tracing']['openTracingSpanContext']; $openTracingSpanBaggages = $ctx['tracing']['openTracingSpanBaggages']; // jaegerEndpoint is confidential, do not print it out easily $jaegerEndpoint = $ctx['tracing']['jaegerEndpoint']; $logger->info($openTracingSpanContext); $logger->info($openTracingSpanBaggages['key1']); return 'success'; }
Java:
package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { String spanContext = context.getTracing().getOpenTracingSpanContext(); String jaegerEndpoint = context.getTracing().getJaegerEndpoint(); String spanBaggage = context.getTracing().getOpenTracingSpanBaggages().get("key1"); outputStream.write(new String("success").getBytes()); } }
カスタムランタイムまたはカスタムコンテナでは、ヘッダーを取得するだけで済みます。 Goは次の例で使用されます:
spanContext := req.Header.Get('x-fc-tracing-opentracing-span-context') spanBaggages := req.Header.Get('x-fc-tracing-opentracing-span-baggages') jaegerEndpoint := req.Header.Get('x-fc-tracing-jaeger-endpoint')
サンプリングルールのカスタマイズ
サンプリングルールをカスタマイズするには、Managed Service for OpenTelemetryコンソールにログインし、リモートサンプリングルールを設定します。 詳細については、「Jaegerを使用したリモートサンプリングポリシーの設定」をご参照ください。 設定が完了すると、サンプリングを実行するように設定したリモートサンプリングルールが使用されます。
Managed service for OpenTelemetryのFunction Computeに対応するサービス名はfc-tracingです。 デフォルトでは、RatelimitingSamplerが使用され、1秒あたり1回のリクエストのレートでサンプリングが実行されます。
デフォルトでは、Function Computeは次のサンプリングルールを使用します。
{
"default_strategy": {
"type": "ratelimiting",
"param": 1,
}
}
有効化の方法
OpenTelemetryのマネージドサービスを有効にする方法については、「トレース分析の有効化」をご参照ください。