本文介紹Function Compute整合鏈路追蹤功能的背景、使用情境、核心功能、採樣規則配置和開啟方式。
背景介紹
阿里雲可觀測鏈路 OpenTelemetry版基於OpenTracing標準,相容開源社區,為分布式應用的開發人員提供了完整的分布式調用鏈查詢和診斷,分布式拓撲動態發現,應用效能即時匯總等功能。
Function Compute與鏈路追蹤整合,支援使用Jaeger上傳鏈路資訊,使您能夠跟蹤函數的執行,協助您快速分析和診斷Serverless架構下的效能瓶頸,提高Serverless情境的開發診斷效率。
使用情境
當Function Compute與鏈路追蹤整合後,您可以記錄請求在Function Compute的耗時時間、查看函數的冷啟動時間、記錄函數內部時間的消耗等。鏈路追蹤功能可以協助您排查以下問題:
函數執行總逾時,需要定位函數的效能瓶頸。
函數執行時間很短,但是端對端時延很長時,需要定位相關原因。
分布式系統中,請求橫跨多個雲端服務,需要分析和診斷函數的效能瓶頸。
核心功能
Function Compute的鏈路追蹤功能可以串聯整個調用鏈,包含以下核心功能:
自動記錄Function Compute內部關鍵步驟耗時時間。更多資訊,請參見自動記錄Function Compute內部關鍵步驟耗時。
串聯上遊服務:如果請求Header中帶有鏈路上下文資訊,則Function Compute會根據上下文建立子鏈路。更多資訊,請參見串聯上遊服務。
串聯下遊服務:Function Compute會將鏈路上下文傳入到函數Context參數中,協助您追蹤函數內部調用鏈路。更多資訊,請參見串聯下遊服務。
查看應用拓撲。
查看錯誤介面執行情況,定位錯誤原因。
自動記錄Function Compute內部關鍵步驟耗時
服務開啟鏈路追蹤功能後,您預設可以看到以下調用鏈。
Span名稱說明如下:
InvokeFunction:當前請求在Function Compute的總停留時間。
ColdStart:函數系統層冷啟動的時間,冷啟動不是每次調用都出現,只在重新申請執行環境時會進行冷啟動。
PrepareCode:函數下載代碼或下載自訂鏡像的時間,如果PrepareCode時間過長,您可以適當精簡程式碼封裝來縮短準備代碼的時間。
RuntimeInitialization:執行環境啟動的時間,包含啟動執行個體的時間、執行個體健全狀態檢查時間。在自訂運行時和自訂鏡像中,如果RuntimeInitialization執行時間過長,需要檢查一下對應的HTTP Server和鏡像的啟動行為。
Initializer:初始化函數的執行時間,初始化函數若且唯若容器冷啟動的時候才會被執行。
Invocation:函數的執行時間,您可以在函數中擷取到Invocation的上下文,詳細記錄函數調用中的耗時。
應用程式名稱:Function Compute產生的應用命名方式為FC:ServiceName/FunctionName
當請求沒有遇到冷啟動時,鏈路中沒有冷啟動時間和Initializer的時間。調用鏈如下所示。
串聯上遊服務
服務開啟鏈路追蹤後,如果請求Header中帶有鏈路上下文資訊SpanContext,則Function Compute會根據上下文建立子鏈路。
Function Compute識別的鏈路上下文要求標頭如下:
x-fc-tracing-opentracing-span-context
:用於傳遞鏈路上下文資訊SpanContext資訊。x-fc-tracing-opentracing-span-context-baggage-
:用於傳遞跨內容相關的Baggage資訊。如果有多個Baggage則需要上傳多個Header,例如
x-fc-tracing-opentracing-span-context-baggage-key1: val1
,x-fc-tracing-opentracing-span-context-baggage-key2: val2
。
在調用函數時添加鏈路上下文資訊Header即可注入上下文資訊。
以Node.js為例:
'use strict';
const FCClient = require('@alicloud/fc2');
/*
阿里雲帳號AccessKey擁有所有API的存取權限,建議您使用RAM使用者進行API訪問或日常營運。
建議不要把AccessKey ID和AccessKey Secret儲存到工程代碼裡,否則可能導致AccessKey泄露,威脅您帳號下所有資源的安全。
本樣本以將AccessKey和AccessSecretKey儲存在環境變數實現身分識別驗證為例。
運行本樣本前,請先在本地環境中設定環境變數ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
在FC Runtime運行環境下,配置執行許可權後,ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET環境變數會自動被設定。
*/
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 {
// 注入Span Context Header資訊。
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會將鏈路上下文傳入到函數中,協助追蹤函數內部的調用鏈路。
對於內建Runtime,可以通過
context.tracing
擷取鏈路上下文資訊。對於Custom Runtime或Custom Container,可以通過請求Header擷取Function Compute鏈路上下文資訊。
x-fc-tracing-opentracing-span-context
:Function ComputeInvokeFunction的鏈路上下文,函數內基於此上下文建立追蹤段。x-fc-tracing-opentracing-span-baggages
:經過Base64編碼的跨上下文Baggage。x-fc-tracing-jaeger-endpoint
:Jaeger的Server端地址,您直接將函數中的追蹤段上傳至此地址。
context.tracing
結構樣本如下:
{
"openTracingSpanContext": "5f22f355044a957a:5708f3a95a4ed10:5f22f355044a****:1",
"openTracingSpanBaggages": {
"key1": "val1",
"key2": "val2"
},
"jaegerEndpoint": "http://tracing-analysis-dc-zb-internal.aliyuncs.com/adapt_fcfc@fcfc@fcfc/api/traces"
}
函數中擷取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()); } }
Custom Runtime或Custom Container擷取Header即可,以Golang語言為例:
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')
自訂採樣規則
如果您需要自訂採樣規則,您可以登入可觀測鏈路 OpenTelemetry版控制台設定遠程採樣規則。更多資訊,請參見使用Jaeger進行遠程採樣策略配置。配置完成後,Function Compute會使用您設定的遠程採樣規則採樣。
Function Compute在鏈路追蹤中對應的服務名稱為fc-tracing,預設使用的採樣規則為RatelimitingSampler,以每秒1個請求的速率採樣。
Function Compute使用的預設採樣規則如下:
{
"default_strategy": {
"type": "ratelimiting",
"param": 1,
}
}
開啟方式
關於鏈路追蹤功能的開啟方式,請參見配置鏈路追蹤。