監控與觀測
隨著軟件應用從單片架構向分布式微服務體系轉變,應用監控(Monitoring)和觀測(Observability)的需求也隨之提升。兩者存在相同的定義,目的都是為了發現應用程序中的問題。但還是有差別:
- 監控:目的是為了捕獲已知的問題,并將其顯示在儀表盤上,用以了解其發生問題的原因和其發生的具體時間;
- 觀測:采用更底層的方式,即開發人員通過調試代碼的方式從而了解程序的內部狀態。為了幫助監控應用程序的未知問題的最新發展。
應用觀測的三大支柱:
- 指標(metrics):指出是否存在問題,通常是通過告警「發現」
- 調用鏈(traces):標明問題點在哪里,「定位」
- 日志(logs):協助定位產生問題的根本原因,「分析」
應用可觀測的好處:
- 找出潛在隱患
- 降低告警疲勞
- 更快發布產品
- 提高自動化程度
- 提高開發生產力
OpenTracing
OpenTracing,制定一套無關廠商、無關平臺的協議標準,使開發人員只需要修改Tracer就可以更迅捷的添加或更換底層監控的實現。2016年CNCF正式接納OpenTracing,順利成為CNCF第三個項目,前兩個項目都已成為云原生及開源領域的事實標準:Kubernetes和Prometheus。由此也可以看到行業對于可觀測及統一標準的重視程度。GitHub。
OpenTracing由API規范、實現該規范的框架和庫,以及項目文檔組成,并進行以下努力:
- 后臺無關的API接口標準化:被追蹤的服務只需要調用相關API接口,就可被任何實現這套接口的追蹤后臺支持;
- 對跟蹤最小單位Span管理標準化:定義開始Span,結束Span和記錄Span耗時的API;
- 進程間跟蹤數據傳遞方式標準化:定義API方便追蹤數據的傳遞;
- 多語言應用支持;多跟蹤器支持,Zipkin、LightStep、Appdash;可輕松集成到gRPC、Flask、DropWizard、Django和Go Kit等框架中。
術語
包括:
- Traces:記錄經過分布式系統的請求活動,一個Trace是Spans的有向無環圖;
- Spans:一個Trace中表示一個命名的,基于時間的操作。Spans嵌套形成Trace樹。每個Trace包含一個根Span,描述端到端的延遲,其子操作也可能擁有一個或多個子Spans;
- Metrics:在運行時捕獲的關于服務的原始度量數據。Observer支持通過異步API來采集數據,每個采集間隔采集一個數據;
- Context:一個Span包含一個Span Context,它是一個全局唯一的標識,表示每個Span所屬的唯一請求,以及跨服務邊界轉移Trace信息所需的數據。OpenTelemetry也支持correlation context,可以包含用戶定義的屬性。correlation context不是必要的,組件可以選擇不攜帶和存儲該信息;
- Context Propagation:表示在不同的服務之間傳遞上下文信息,通常通過HTTP首部。除Tracing外,還可用于執行A/B測試。支持通過多個協議的Context Propagation來避免可能發生的問題,但需要注意的是,在自己的應用中最好使用單一的方法;
- References:Spans之間建立連接的描述,目前有兩種類型,ChildOf和FollowsFrom。
Maven
io.opentracing
是官方核心庫,包含主要的接口和規范,如Tracer、Span、SpanContext等,其下的artifactId包括:
- opentracing-api:定義OpenTracing的核心API;
- opentracing-util:提供幫助工具,如GlobalTracer;
- opentracing-noop:提供無操作的實現,用于無跟蹤時的默認行為。
最后發布日期停留在2019年5月份,Maven依賴如下:
<dependency><groupId>io.opentracing</groupId><artifactId>opentracing-api</artifactId><version>0.33.0</version>
</dependency>
<dependency><groupId>io.opentracing</groupId><artifactId>opentracing-noop</artifactId><version>0.33.0</version>
</dependency>
io.opentracing.contrib
是OpenTracing社區貢獻的擴展庫組件,用于與各種第三方框架和工具進行集成。目的是簡化OpenTracing與常見工具和框架的集成,降低接入成本。
其下的artifactId包括:
opentracing-tracerresolver
:幫助在運行時解析和加載具體的Tracer實現,如Jaeger或Zipkin;opentracing-spring-cloud
:為Spring Cloud應用提供OpenTracing集成;opentracing-jdbc
:為JDBC提供數據庫調用的自動跟蹤;opentracing-kafka
:用于跟蹤Kafka消息的生產和消費。
一張圖感受一下到底有多少個artifactId:
最后發布日期停留在2019年6月份。
Jaeger和OpenTracing
Jaeger是最早實現OpenTracing API的分布式追蹤系統之一,由Uber開發,后來捐贈給CNCF。
Jaeger 1.x和2.x版本都支持OpenTracing API,可直接使用opentracing-api
庫進行分布式追蹤開發。
OpenCensus
官網,其發起者是谷歌,也就是最早提出Tracing概念的公司,可理解為Google Dapper的社區版。和OpenTracing最大的不同在于除Tracing外,還包括Metrics指標監控;并不是單純的規范制定,還包括數據采集的Agent、Collector等。有眾多追隨者,如微軟。GitHub。
除沿用OpenTracing的相關術語之外,OpenCensus也定義一些新術語:
- Tags:允許在記錄時將指標與維度相關聯。從而能夠從不同角度分析測量結果;
- Stats:收集庫和應用記錄的可觀測結果,匯總、導出統計數據,并包括Recording、Views(聚合度量查詢)兩部分;
- Trace:除Opentracing所提供的Span屬性之外,OpenCensus還支持Parent SpanId、Remote Parent、Attributes、Annotations、Message Events、Links等屬性;
- Agent:OpenCensus Agent是一個守護進程,允許OpenCensus的多語言部署使用Exporter。與傳統上為每個語言庫和每個應用程序刪除和配置OpenCensus Exporter不同,使用OpenCensus Agent,只需為其目標語言單獨啟用OpenCensus Agent Exporter。對于運維團隊而言,實現單個Exporter管理并從多語言應用程序中獲取數據,將數據發送到所選擇的后端。與此同時,盡可能的減少反復啟動或部署對于應用的影響。Agent還附帶Receivers,使Agent直通后端,去接收可觀測數據并將其路由到所選擇的Exporter。如Zipkin、Jaeger或Prometheus。
- Collector:OpenCensus的重要組成部分,由Go編寫,可從任何可用Receivers的應用中接受流量,而不用關注編程語言以及部署方式。對于提供Metrics和Trace的服務或應用而言,只需要一個Exporters導出組件,就能從多語言應用中獲取數據。對于開發者而言,只需要管理維護單個Exporter,所有應用都使用OpenCensus Exporter發送數據。開發人員自由選擇將數據發送到業務所需的后端,并隨時進行更好。為了解決通過網絡發送大量數據可能需要處理發送失敗的問題,Collector具有緩沖和重試功能,可確保數據完整性與可用性。
- Exporters:OpenCensus 可通過各種 Exporter 實現將相關數據上傳到各種后端,比如:Prometheus for stats、OpenZipkin for traces、Stackdriver Monitoring for stats and Trace for traces、Jaeger for traces、Graphite for stats。
遵循OpenCensus協議的產品有Prometheus、SignalFX、Stackdriver和Zipkin。
OpenTelemetry
OpenTracing項目在2019年停止更新,后續其功能被OpenTelemetry,簡稱OTel,所取代。GitHub。
遙測數據(Telemetry Data)是跨科學領域的通用術語,描述一種從遠程位置收集數據集用于測量系統健康狀況的行為。在DevOps中,系統指的就是軟件應用,要收集的數據就是日志、調用鏈和指標。
架構簡圖
在OpenTracing基礎上引入的術語:
- Metrics:在運行時捕獲的關于服務的原始度量數據。Observer支持通過異步API來采集數據,每個采集間隔采集一個數據;
OpenTracing、OpenCensus和OpenTelemetry
特性 | OpenTracing | OpenCensus | OpenTelemetry |
---|---|---|---|
簡介 | 最早的分布式追蹤標準,定義統一的接口和規范,允許用戶切換具體的追蹤器 | Google發起,支持Tracing,Metrics,并提供數據采集Agent和Collector | OpenTracing和OpenCensus合并后產物,目的是構建一個統一的、全面的可觀測性標準,支持分布式追蹤和指標采集 |
覆蓋范圍 | 僅支持分布式追蹤,不涉及Metrics或Logs | 支持Traces、Metrics,但不包含Logs | 支持分布式追蹤、指標、日志;提供自動代碼注入和Collector(Agent/Gateway模式) |
生態兼容性 | CNCF托管,被Jaeger、Zipkin等支持 | 微軟等公司加入支持,生態較強;缺乏統一的CNCF支持 | 成為CNCF的標準,可被更多工具支持;兼容OpenTracing和OpenCensus,提供平滑遷移路徑 |
標準化程度 | API標準 | SDK+采集架構 | 統一API+SDK+協議 |
數據采集 | 依賴第三方實現 | 自帶Agent/Collector | 自帶OTLP Collector |
當前狀態 | 2019年停止發布Release,GitHub于2023年5月24日歸檔 | GitHub于2023年8月1日歸檔 | 活躍開發中,逐步取代OpenTracing和OpenCensus |
對應替代關系:
io.opentracing:opentracing-api
→io.opentelemetry:opentelemetry-api
;io.opentracing:opentracing-util
→io.opentelemetry:opentelemetry-sdk
;io.opentracing.contrib:opentracing-tracerresolver
→無直接替代,OpenTelemetry提供標準化的SDK初始化方式;- 其他
io.opentracing.contrib
庫可被OpenTelemetry的自動檢測和集成工具替代。
遷移指南:OpenTelemetry項目提供從OpenTracing遷移到OpenTelemetry的官方指南,其中列舉關鍵變化和替代組件。
<dependency><groupId>io.opentelemetry.javaagent</groupId><artifactId>opentelemetry-javaagent-api</artifactId><version>0.16.1</version><scope>runtime</scope>
</dependency>
Jaeger和OpenTelemetry
互補:
- OpenTelemetry:專注于數據采集和標準化,包括API、SDK、Collector;
- Jaeger:Jaeger Exporter將數據從OpenTelemetry Collector或SDK導出到Jaeger后端;專注于追蹤數據的存儲、分析和可視化。
OTLP
OpenTelemetry Protocol,OpenTelemetry定義的標準數據格式。OTLP取代舊版協議(如Jaeger或Zipkin的專用協議),成為OpenTelemetry默認導出格式。
核心特性:
- 多數據類型支持:統一傳輸跟蹤、指標和日志;
- 多傳輸協議:默認使用gRPC,支持HTTP/JSON;
- 高效編碼:基于Protocol Buffers的二進制編碼,減少帶寬占用;
- 端到端可靠性:內置重試、隊列和批處理機制。
架構
OTLP協議的關鍵優勢:
- 統一三種遙測數據的傳輸方式;
- 通過PB實現高性能序列化;
- 靈活的傳輸層支持(gRPC/HTTP)。
Jaeger
版本
版本1.*
和2.*
,同時在更新release發布中。
版本區別:
在Jaeger 1.x中
- 前端API:
Jaeger提供完整的分布式追蹤生態,包括一個實現OpenTracing標準的客戶端(通過jaeger-client
庫)。開發者可以直接調用Jaeger的API(如JaegerTracer)來生成和發送追蹤數據。 - 后端處理:
Jaeger同時作為追蹤系統的后端,包含以下組件:- Agent:接收應用程序發來的Span數據;
- Collector:處理和存儲追蹤數據到數據庫;
- Query:提供數據查詢和UI可視化。
Jaeger 1.x是全棧式分布式追蹤解決方案,包括前端API和后端功能。
在Jaeger 2.x中:
- 前端API的弱化:不再專注于提供客戶端API,而是轉向支持OpenTelemetry的標準API和SDK。應用程序需要直接調用OpenTelemetry的API(如Tracer、Span),而不是依賴Jaeger的API。官方建議是使用OpenTelemetry SDK進行追蹤數據的采集。
- 后端功能的強化:Jaeger 2.x專注于成為分布式追蹤的后端系統,處理追蹤數據的接收、存儲和可視化:
- Collector:支持OpenTelemetry數據格式,兼容多種傳輸協議,如gRPC和HTTP;
- 存儲:支持多種存儲后端,如ES、Cassandra、Kafka等;
- Query和UI:繼續提供可視化和分析功能,讓開發者能查詢和分析追蹤數據。
Jaeger版本與OpenTracing、OpenTelemetry
1.x版本:
- 支持OpenTracing API,用戶通過
io.opentracing
或io.opentracing.contrib
配置Jaeger作為追蹤器; - 完全依賴OpenTracing的規范和生態。
2.x版本:
- 增加對OpenTelemetry的支持,同時兼容OpenTracing;
- 提供新的組件和數據管道,集成OpenTelemetry Collector;
- 主要作為分布式追蹤的后端使用(Collector、存儲、查詢等),不再專注于前端API的實現;
- 推薦使用OpenTelemetry API,而不是繼續使用OpenTracing。
推薦閱讀
- https://www.echo.cool/docs/category/opentelemetry-教程
- 從Opentracing、OpenCensus到OpenTelemetry,看可觀測數據標準演進史
- OpenTracing文檔中文版翻譯-吳晟
- https://github.com/1046102779/opentracing