目錄
- 引言
- 一、OpenTelemetry是一套可觀測性標準協議
- 二、分布式追蹤(?Trace?)是OpenTelemetry的核心功能之一
- 三、OpenTelemetry的架構原理
- 四、OpenTelemetry的分布式追蹤(?Trace?)實踐
- 1、準備PHP環境
- 2、下載SDK
- 3、編寫實例代碼
- 4、run起來
- 5、otlp協議上報到存儲介質平臺
引言
與前篇談到的MCP協議類似,OpenTelemetry也是一套標準協議。每一套協議的誕生一定是為了解決已存在的某難題的,就好比得先有四通八達的馬路和滿街的汽車,交通規則的誕生才有意義,如果只是三三兩兩的車流,似乎交通規則就沒那么大的價值。
OpenTelemetry 的前身是 OpenTracing 和 OpenCensus 兩個項目。OpenTracing 主要關注分布式追蹤,而 OpenCensus 則側重于指標和跨語言的統計信息收集。 2019年,這兩個社區決定合作并融合各自的特性,形成了新的開源項目——OpenTelemetry。這一舉措旨在提供一個全面的解決方案,能夠同時處理追蹤、指標和其他形式的遙測數據,并且支持多種編程語言和框架。OpenTelemetry 在之后的時間里不斷完善和擴展其功能,并于2020年正式發布了首個穩定版本。
OpenTelemetry 的誕生是為了應對現代軟件系統架構中日益增長的監控和追蹤需求,特別是分布式系統和云原生環境的復雜性。它的出現是為了解決多個監控工具之間的互操作性問題,以及提供一種統一的方式來收集、處理和分析遙測數據,從而幫助開發和運維團隊更有效地理解和優化他們的服務。
一、OpenTelemetry是一套可觀測性標準協議
OpenTelemetry是一套由CNCF主導的云原生可觀測性標準協議,全稱:OpenTelemetry Protocol,簡稱OTLP,旨在提供一種統一的方式來收集、處理和分析 分布式追蹤(trace)、日志(logging)和度量(metrics) 數據。
OpenTelemetry定義了可觀測性的幾個方面的標準:trace、logs、metrics、resources。
-
追蹤(Tracing):
提供了分布式追蹤的功能,可以跟蹤請求在分布式系統中的完整路徑,幫助識別性能瓶頸和故障點。 -
指標(Metrics):
收集系統的各種性能指標,如請求速率、錯誤率、資源使用情況等,用于監控系統的健康狀況和性能。 -
日志(Logs):
雖然 OpenTelemetry 主要關注追蹤和指標,但它也支持與日志系統的集成,以便于將日志數據與其他類型的遙測數據關聯起來。
二、分布式追蹤(?Trace?)是OpenTelemetry的核心功能之一
OpenTelemetry與trace的關系主要體現在OpenTelemetry是用于分布式追蹤的標準和工具集,而trace是分布式追蹤的基本單位。?
分布式追蹤(?Trace?)是OpenTelemetry的核心功能之一,用于監控和分析微服務架構中的請求傳播路徑和性能問題?。?Trace?在分布式系統中扮演著關鍵角色。它記錄了一個請求在多個服務之間傳播的完整路徑,幫助開發者理解請求在系統中的行為和性能表現。一個trace由多個span組成,每個span代表請求中的一個操作或工作單元,記錄了操作的具體信息,如開始和結束時間、操作類型、結果狀態等?。通過這些信息,開發者可以重構事務的完整旅程,定位和解決性能問題和故障?。
可觀測性一個很重要的領域 Trace 有兩個業界標桿:一個是OpenTracing,另一個OpenCensus。
OpenTracing其實是一個規范,jaeger就是基于opentracing實現的開源工具;
OpenCensus則是由google開源的度量工具;
簡單來說,這兩者在可觀測性領域功能高度重合,因此,在CNCF主導下進行了合并形成opentelemetry項目,OpenTracing跟penCensus共同推進opentelemetry,兩者的官網也赫赫表達基本不再維護。同時OpenTelemetry也致力于trace、logging、metrics間的關聯性。
三、OpenTelemetry的架構原理
我們重點先來看數據收集管道。
Data Collection Pipeline(數據收集管道)包含:
- Collector:OpenTelemetry Collector是一個開源的組件,用于接收、處理和導出遙測數據。它可以部署在各個服務節點上,也可以作為一個集中式的處理層。
- Receiver:接收來自不同來源的遙測數據。
- Processor:處理和轉換數據,例如過濾、聚合等。
- Exporter:將處理后的數據導出到各種后端系統,如Jaeger、Prometheus、Zipkin等。
可不要小看這些概念,在寫代碼的時候處理問題可有用了。從上面的圖可以看出數據整個流向的過程,當數據經過Collector采集器之后,就可以Exporter到各種存儲介質上了。細心的小伙伴們發現了,OpenTelemetry并未直接實現Exporter之后的數據存儲,而是交給遵循了OpenTelemetry協議的Jaeger、Prometheus、Zipkin等存儲平臺。通俗理解就是只要數據格式是遵循OpenTelemetry的上報,都可以進行數據標準化等處理,并被上報到任意遵循了OpenTelemetry協議的存儲介質平臺上進行下一步的遙測觀察和統計。
OpenTelemetry內心OS:“我只是個協議而已,存儲就交給別人來做吧,要實現存儲這得是另外的價錢~~”。
四、OpenTelemetry的分布式追蹤(?Trace?)實踐
我們知道OpenTelemetry有幾個方面的標準:分布式追蹤(trace)、日志(logging)和度量(metrics)。這就意味著他可以用來做很多不僅僅是分布式追蹤(trace)之外的事,比如K8s的監控,服務的監控等等。我們這里之所以當獨講分布式追蹤(trace),主要是因為其不僅是OpenTelemetry的核心功能,在監控和分析微服務架構中的請求傳播路徑和性能問題?上目前也是普遍流行的解決方案。
那么我們如何基于OpenTelemetry實現鏈路追蹤呢?
我們先來看OpenTelemetry官網的介紹。
光說不練假把式。于是我們以PHP為例來一步一步詳細操作下來簡單demo實踐一下。其他語言同理。
1、準備PHP環境
它說PHP版本要求至少7.4+,而如果希望0代碼非入侵式的接入PHP版本至少要8.0+。
OpenTelemetry部分是支持無縫接入的,也就是非入侵式的服務監控和分布式追蹤,當然如果你需要個性化地“埋點”自己的服務調用鏈路情況,那就可以自己手動用代碼實現了(代碼侵入式)。
由于小馬的本地已經安裝了PHP相關環境,特意檢查了下版本號符合條件,環境準備完畢。
2、下載SDK
參考官網案例,我們進入代碼目錄下,運行composer命令安裝SDK依賴,composer.json文件需要安裝的依賴包配置參考如下。
但這里需要注意,市面上開源SDK實現可能會有很多,不管你依賴于哪個SDK,只要遵循OpenTelemetry協議即可。
{"name": "vendor/m.server3","description": "description","minimum-stability": "stable","license": "proprietary","authors": [{"name": "小馬過河R","email": "email@example.com"}],"require": {"slim/slim": "^4","slim/psr7":"^1","nyholm/psr7": "^1","open-telemetry/opentelemetry": "*","open-telemetry/api": "*","open-telemetry/sdk": "*","symfony/http-client": "^5.4","guzzlehttp/promises": "^2.2","php-http/message-factory": "^1.1","php-http/httplug": "^2.4"},"config": {"allow-plugins": {"php-http/discovery": true}}
}
3、編寫實例代碼
進入代碼目錄下,創建index.php文件。
為了驗證,我們先將TRACES輸出到console查看。
putenv('OTEL_SERVICE_NAME=demo1');
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
putenv('OTEL_TRACES_EXPORTER=console');//console otlp
putenv('OTEL_METRICS_EXPORTER=none');
putenv('OTEL_LOGS_EXPORTER=console');
#putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');
#putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318');//http:4318,grpc:4317
#putenv('OTEL_EXPORTER_OTLP_HEADERS=');
#putenv('OTEL_PROPAGATORS=b3,baggage,tracecontext');use OpenTelemetry\API\Globals;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;require_once __DIR__ . '/vendor/autoload.php';$tracer = Globals::tracerProvider()->getTracer('demo-tracer-name');$app = AppFactory::create();$app->get('/rolldice', function (Request $request, Response $response) use ($tracer) {$span = $tracer->spanBuilder('manual-span')->startSpan();try {$span->setAttribute('user_id', 12345);$result = random_int(1, 6);$response->getBody()->write(strval($result));$span->addEvent('rolled dice', ['result' => $result])->end();return $response;} catch (Exception $e) {$span->setStatus($e->getCode(), $e->getMessage());$span->end();$response->getBody()->write('exception');return $response;}});$app->run();
4、run起來
我們在代碼目錄下執行php -S localhost:8080
命令,讓程序監聽8080端口。
回到瀏覽器訪問路由http://localhost:8080/rolldice
。我們看到了響應返回。
而console如約打出了日志信息。
好了,我們的demo實現完畢了,看起來超級簡單,對吧。
5、otlp協議上報到存儲介質平臺
我們剛剛為了方便演示,把日志輸出在console,但是實際生產場景中肯定不是這樣的,那如果我要上報到諸如Jaeger、Prometheus、Zipkin等的后端系統或存儲平臺,要如何處理?很簡單,修改配置即可。詳細的可以參看官方的配置介紹文檔。小馬這里主要拎幾個重要的配置項來介紹。
//something todo...
putenv('OTEL_TRACES_EXPORTER=otlp');//改成otlp
#putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');//默認http
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318');//填寫ENDPOINT上報地址,http:4318,grpc:4317
putenv('OTEL_EXPORTER_OTLP_HEADERS=');//如果有些平臺是要求傳鑒權token,可以通過HEADERS透傳//something todo...
好了,這就改完了,重新run起來。
在平臺你將看到如下類似效果(由于信息敏感小馬就不貼自己實驗的截圖啦),日志信息將比console展示更完整和豐富。
當然,至于TRACES相關的知識點以及如何合理規劃設置span不是本文重點,小馬這里就不再贅述啦。