OpenTelemetry 項目解讀

點擊一鍵訂閱《雲薦大咖》專欄,獲取官方推薦精品內容,學技術不迷路!

 

隨着分佈式應用越來越普遍,分佈式應用需要依賴強大的可觀測性設施來提供監控保障,強大的可觀測性設施需要依賴高質量的遙測數據。雖然已經有許多開源或者商業供應商提供了遙測數據監測採集方案。但是在沒有統一標準的情況下,採集的遙測數據兼容性差,維護監測客戶端也給使用者帶來沉重的負擔。

Opentelemetry 可以爲開發者們提供統一的,與第三方無關的遙測數據採集方案,以解決上述的各種問題。

源起

Opentelemetry 源於 OpenTracing 與 OpenCensus 兩大開源社區的合併而來。OpenTracing 在 2016 年由 Ben Sigelman 發起,旨在解決開源 Tracing 實現重複開發監測客戶端, 數據模型不統一, Tracing 後端兼容成本高的問題。OpenCensus 則是由 Google 內部實踐而來,結合了 Tracing 和 Metrics 的監測客戶端開源工具包。

由於兩大開源社區各自的影響力都不小,而存在兩個或多個 Tracing 的標準這個事情本身跟社區組建的主旨相違背。於是兩大開源社區一拍即合,成立了 OpenTelemetry。

爲什麼需要

從使用者角度來看,接入 Tracing 監測客戶端,對業務代碼有一定入侵性。一旦接入了一個供應商的監測客戶端,就很難切換到其他供應商提供的監測客戶端。而從 Tracing 服務端供應商的角度來說,服務端除了要能夠處理自己 Tracing 客戶端的數據外,還需要兼容其他供應商 Tracing 客戶端產生的數據,維護成本越來越高。尤其是在分佈式應用逐漸普及的情況下,如文章開頭所說, Opentelemetry 的價值更加明顯。

Opentelemetry 項目組成

Opentelemetry 的項目主要分爲四個部分內容

  • 跨語言規範說明
  • 收集、轉換、轉發遙測數據的工具 Collector
  • 各語言監測客戶端 API & SDK
  • 自動監測客戶端與第三方庫 Instrumentation & Contrib

跨語言規範說明

規範說明包含話題內容比較廣泛。其中有包含遙測客戶端內部實現所需要的規範,也有包含遙測客戶端與外部通信所需要實現的協議規範。

代碼倉庫:opentelemetry-specification

遙測客戶端內部實現所需要的規範,如監測客戶端基本架構、設計原則,遙測信號(Traces/ Metrics/ Logs)與輔助對象(Baggage/ Context/ Propagator)的概念與模型定義,實現遙測客戶端需要實現的類與功能的設計等。這部分內容本文就不做詳細介紹,可以在 specification/overview.md 以及相應對象文件夾下面的 datamodel.md/ api.md/ sdk.md 可以進行查閱。

遙測客戶端與外部通信所需要實現的協議規範主要是指 OpenTelemetry Protocol (簡稱 OTLP)。OTLP 是 Opentelemetry 原生的遙測信號傳遞協議,雖然在 Opentelemetry 的項目中組件支持了 Zipkin v2 或 Jaeger Thrift 的協議格式的實現,但是都是以第三方貢獻庫的形式提供的。只有 OTLP 是 Opentelemetry 官方原生支持的格式。

OTLP 的數據模型定義是基於 ProtoBuf 完成的,如果你需要實現一套可以收集 OTLP 遙測數據的後端服務,那就需要了解裏面的內容,對應可以參考代碼倉庫:

代碼倉庫:opentelemetry-proto

收集、轉換、轉發遙測數據的工具 Collector

在 Tracing 實踐中有一個原則,遙測數據收集過程需要與業務邏輯處理正交。意思就是遙測數據收集並傳遞到遙測後端服務的過程不佔用業務邏輯的信道/線程,儘量較少監測客戶端對原有業務邏輯的影響。Collector 是基於這個原則實踐的產物。

代碼倉庫:opentelemetry-collector

從架構層面來說,Collector 有兩種模式。一種是把 Collector 部署在應用相同的主機內(如 K8S 的 DaemonSet),或者部署在應用相同的 Pod 裏面 (如 K8S 中的 Sidecar),應用採集到的遙測數據,直接通過迴環網絡傳遞給 Collector。這種模式統稱爲 Agent 模式。

另一種模式是把 Collector 當作一個獨立的中間件,應用把採集到的遙測數據往這個中間件裏面傳遞。這種模式稱之爲 Gateway 模式。

兩種模式既可以單獨使用,也可以組合使用,只需要數據出口的數據協議格式跟數據入口的數據協議格式保持一致。

Opentelemetry Architecture

在 Collector 內部設計中,一套數據的流入、處理、流出的過程稱爲 pipeline。一個 pipeline 有三部分組件組合而成,它們分別是 receiver/ processor/ exporter。

  • receiver
    • 負責按照對應的協議格式監聽接收遙測數據,並把數據轉給一個或者多個 processor
  • processor
    • 負責做遙測數據加工處理,如丟棄數據,增加信息,轉批處理等,並把數據傳遞給下一個 processor 或者傳遞給一個或多個 exporter
  • exporter
    • 負責把數據往下一個接收端發送(一般是遙測後端),exporter 可以定義同時從多個不同的 processor 中獲取遙測數據

Collector Pipeline

從上面的設計可以看出,Collector 除了提供讓遙測數據收集與業務邏輯處理正交的能力,還充當了遙測數據對接遙測後端的適配器。Collector 可以接收 otlp, zipkin, jaeger 等任意格式的數據,然後以 otlp, zipkin, jaeger 等任意格式的數據轉發出去。這一切只取決於你需要輸入或輸出的格式是否有對應的 receiver 和 exporter 實現。 otlp 相關的實現都是在 opentelemetry-collector 倉庫中。而 otlp 以外的協議實現,則是可以參考下面代碼倉庫。

代碼倉庫:opentelemetry-collector-contrib

各語言監測客戶端 API & SDK

Opentelemetry 爲每種語言提供了基礎的監測客戶端 API & SDK 包。這些包一般都是根據 opentelemetry-specification 裏面的建議與定義,以及結合語言自身的特點,實現了在客戶端採集遙測數據的基本能力。如元數據在服務間、進程間的傳遞,Trace 添加監測與數據導出,Metrics 指標的創建、使用及數據導出等。以下爲各語言監測客戶端 API & SDK 包對應的代碼倉庫表。

語言

倉庫地址

C++

opentelemetry-cpp

.NET

opentelemetry-dotnet

Erlang

opentelemetry-erlang-api & opentelemetry-erlang

Golang

opentelemetry-go

Java

opentelemetry-java

javaScript

opentelemetry-js-api & opentelemetry-js

PHP

opentelemetry-php

Python

opentelemetry-python

Ruby

opentelemetry-ruby

Rust

opentelemetry-rust

Swift

opentelemetry-swift

按照 Opentelemetry 項目的規劃,2021 年上半年大部分組件完成 Tracing 的支持。以目前的時間點(2021年12月)來看,C++/.NET/Golang/Java/Javascript/Python/Ruby 監測客戶端對 Tracing 支持已經進入 Stable 狀態。 Erlang/Rust/Swift 監測客戶端對 Tracing 支持則是進入了 Beta 測試階段。

而 Opentelemetry 項目規劃對於 Mertics 的支持則晚一些。希望在 2021 年下半年大部分組件能夠完成 Metrics 的支持。以目前情況來看,各語言客戶端包對於 Metrics 支持還處在 Alpha 測試階段。 而對於 Logs 的支持,則是計劃在 2022 年開始。

Instrumentation & Contrib

如果單純使用監測客戶端 API & SDK 包,許多的操作是需要修改應用代碼的。如添加 Tracing 監測點,記錄字段信息,元數據在進程/服務間傳遞的裝箱拆箱等。這種方式具有代碼侵入性,不易解耦,而且操作成本高,增加用戶使用門檻。這個時候就可以利用公共組件的設計模式或語言特性等來降低用戶使用門檻。

利用公共組件的設計模式,例如在 Golang 的 Gin 組件,實現了 Middleware 責任鏈設計模式。我們可以引用 github.com/gin-gonic/gin 庫,創建一個 otelgin.Middleware,手動添加到 Middleware 鏈中,實現 Gin 的快速監測。

利用語言特性的,例如 Java 使用 Java Agent 的能力與 bytebuddy 字節碼織入技術,在 Java 應用啓動之前找到對應類和方法,修改字節碼注入監測,實現對指定類的自動監測。

理論上來說,快速監測依賴於客戶端 API & SDK,自動監測則依賴於快速監測。但是實際操作卻並沒有按理論的來。如 Java 語言利用 Java Agent 與 bytebuddy 技術可以實現對指定開源組件實現全自動監測的,所以就沒有單獨提供快速監測(在 OpenTracing 裏面是有分開的)。

語言

快速監測

自動監測

Python

opentelemetry-python-contrib

opentelemetry-python-contrib

javaScript

opentelemetry-js-contrib

opentelemetry-js-contrib

Ruby

opentelemetry-ruby

opentelemetry-ruby

Java

(x)

opentelemetry-java-instrumentation

Golang

opentelemetry-go-contrib

(x)

.NET

opentelemetry-dotnet-contrib

opentelemetry-dotnet-instrumentation

Erlang

opentelemetry-erlang-contrib

 

Rust

opentelemetry-rust

 

Swift

opentelemetry-swift

 

總結

Opentelemetry 的使命是實現收集高質量、大範圍、便攜的遙測數據,讓有效的可觀測性設施成爲可能。它本身並不提供完整的可觀測性解決方案,而是提供了統一的遙測數據採集方案。而如果是需要搭建一套完整的可觀測性設施,還需要搭配相應的監測後端做數據持久化與數據查詢,如 Tracing 後端 zipkin/jaeger/tempo/,metrics 後端 prometheus,logs 後端 loki 等。

 

周東科往期精彩文章推薦:鏈路追蹤(Tracing)的前世今生(上)

 

《雲薦大咖》是騰訊雲加社區精品內容專欄。雲薦官特邀行業佼者,聚焦於前沿技術的落地及理論實踐之上,持續爲您解讀雲時代熱點技術、探索行業發展新機。點擊一鍵訂閱,我們將爲你定期推送精品內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章