ABP VNext + OpenTelemetry + Jaeger:分布式追蹤與調用鏈可視化

ABP VNext + OpenTelemetry + Jaeger:分布式追蹤與調用鏈可視化 🚀


📚 目錄

  • ABP VNext + OpenTelemetry + Jaeger:分布式追蹤與調用鏈可視化 🚀
    • 背景與動機 🌟
    • 環境與依賴 📦
      • 必裝 NuGet 包
    • 系統架構概覽 🖥?
    • 跑通示例 🚀
      • `Program.cs`
      • `docker-compose.yml` 🐳
    • 自動 + 手動埋點 🔍
      • 自動埋點
      • 自定義業務 Span
    • 異常與狀態碼標記 ??
    • 日志與 Metrics 關聯 📑
    • Jaeger 部署與高可用 🏗?
    • 采樣策略與性能優化 🛡?
    • 擴展:OTel Collector & Grafana Tempo 🔗


版本說明:本文基于 OpenTelemetry.Extensions.Hosting >=1.4.0 編寫,推薦使用統一的 .AddOpenTelemetry().WithTracing(...).WithMetrics(...) API。

TL;DR

  1. 提供完整 Program.cs + docker-compose.yml 示例 🏃?♂?
  2. 自動 + 手動埋點:支持 HTTP/gRPC、數據庫、外部調用與自定義 Span 🔍
  3. 高性能采樣:Parent-Based + TraceIdRatioBasedSampler,動態可配 ??
  4. 生產級部署:Batch 模式、OTel Collector、日志/Metrics 關聯、異常標記 🚀

背景與動機 🌟

在分布式微服務架構中,調用鏈橫跨多個進程與網絡節點,“誰調用了誰”、“哪些環節慢”成為痛點。
OpenTelemetry(OTel)與 Jaeger 提供了開源、無侵入的端到端分布式追蹤解決方案,幫助我們:

  • 自動化采集:入站 HTTP/gRPC、數據庫、外部 HTTP 等一鍵埋點 📡
  • 自定義業務 Span:靈活埋點關鍵業務邏輯 🛠?
  • 統一可視化:Jaeger UI 或 Grafana Tempo 展示完整調用鏈 📈

本文基于 ABP VNext 6.x + .NET 6+,演示從零搭建到生產級優化,涵蓋自動/手動埋點、采樣策略、異常與日志關聯等最佳實踐。


環境與依賴 📦

  • .NET SDK:6.0+
  • ABP Framework:vNext 6.x
  • OpenTelemetry.Extensions.Hosting:>=1.4.0
  • Jaeger:all-in-one(測試);獨立 Agent/Collector/Storage(生產)
  • 可選:OpenTelemetry Collector、Grafana Tempo、Prometheus/Grafana

必裝 NuGet 包

dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
dotnet add package OpenTelemetry.Instrumentation.SqlClient
dotnet add package OpenTelemetry.Instrumentation.GrpcNetClient
dotnet add package OpenTelemetry.Instrumentation.GrpcAspNetCore
dotnet add package OpenTelemetry.Exporter.Jaeger
dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol

系統架構概覽 🖥?

HTTP/gRPC
DB
HTTP
Metrics
Logs
Client
ABP Service A
SQL Server
ABP Service B
Jaeger Collector
Jaeger UI
Prometheus
Grafana Dashboard
OTel Collector
日志后端
Grafana Tempo
  • 采集:入站 HTTP/gRPC、EF Core/SqlClient、HttpClient、gRPC 客戶端、日志、Metrics
  • 導出:Trace → Jaeger;Metrics → Prometheus;Logs → OTLP → 日志后端;(可選)Trace → Tempo

跑通示例 🚀

啟動 Jaeger (docker-compose)
運行微服務 (dotnet run)
訪問業務 API
生成 Trace/Metric/Log 數據
在 Jaeger UI 查看調用鏈
在 Prometheus 查看 Metrics
在日志后端查看日志

Program.cs

using OpenTelemetry;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Volo.Abp;var builder = WebApplication.CreateBuilder(args);// 1. ABP 模塊注冊
builder.Services.AddApplication<MyProjectHttpApiHostModule>();// 2. OpenTelemetry 注冊(Tracing + Metrics)
builder.Services.AddOpenTelemetry()// Tracing.WithTracing(tracing => tracing.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("OrderService", serviceVersion: "1.0.0")).AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddSqlClientInstrumentation().AddGrpcAspNetCoreInstrumentation().AddGrpcClientInstrumentation().AddSource("MyCompany.MyProduct").AddJaegerExporter(opts =>{opts.AgentHost = builder.Configuration["Jaeger:Host"];opts.AgentPort = int.Parse(builder.Configuration["Jaeger:Port"]!);}, exportProcessorType: ExportProcessorType.Batch).SetSampler(new ParentBasedSampler(new TraceIdRatioBasedSampler(0.1))))// Metrics.WithMetrics(metrics => metrics.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddPrometheusExporter());// 3. 日志關聯 TraceContext
builder.Logging.AddOpenTelemetry(logging =>
{logging.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("OrderService"));logging.IncludeFormattedMessage = true;logging.IncludeScopes = true;logging.ParseStateValues = true;logging.AddOtlpExporter(); // 需要 OpenTelemetry.Exporter.OpenTelemetryProtocol
});var app = builder.Build();// 4. Prometheus 默認抓取端點(/metrics),無需額外配置
app.MapPrometheusScrapingEndpoint();// 5. 啟動 ABP 應用
app.InitializeApplication();
app.Run();

docker-compose.yml 🐳

version: '3.8'
services:jaeger:image: jaegertracing/all-in-one:1.45ports:- "6831:6831/udp"- "16686:16686"- "14250:14250"

快速啟動

  1. docker-compose up -d
  2. dotnet run --project src/MyProject.HttpApi.Host
  3. 訪問 API & http://localhost:16686

自動 + 手動埋點 🔍

自動埋點

  • HTTP/gRPC.AddAspNetCoreInstrumentation().AddGrpcAspNetCoreInstrumentation()
  • 外部調用.AddHttpClientInstrumentation().AddGrpcClientInstrumentation()
  • 數據庫.AddSqlClientInstrumentation()
ClientABP APISQL Server外部服務HTTP 請求SQL 查詢HTTP 調用響應ClientABP APISQL Server外部服務

自定義業務 Span

public class OrderAppService : ApplicationService
{private static readonly ActivitySource Source = new("MyCompany.MyProduct");public async Task ProcessOrderAsync(Guid orderId){using var activity = Source.StartActivity("ProcessOrder");activity?.SetTag("order.id", orderId);try{await _orderManager.HandleOrderAsync(orderId);}catch (Exception ex){activity?.SetStatus(ActivityStatusCode.Error, ex.Message);activity?.RecordException(ex);throw;}}
}

💡 Tip:通過 ABP 攔截器統一埋點:

public class TraceInterceptor : IInterceptor
{private static readonly ActivitySource Source = new("MyCompany.MyProduct");public void Intercept(IInvocation invocation){using var activity = Source.StartActivity(invocation.Method.Name);activity?.SetTag("abp.service", invocation.TargetType.Name);try{invocation.Proceed();}catch (Exception ex){activity?.SetStatus(ActivityStatusCode.Error, ex.Message);activity?.RecordException(ex);throw;}}
}// 注冊攔截器
Configure<AbpInterceptorsOptions>(opts =>opts.Interceptors.Add<TraceInterceptor>()
);

異常與狀態碼標記 ??

  • activity?.SetStatus(ActivityStatusCode.Error, message) 標記失敗 Span
  • activity?.RecordException(ex) 記錄異常詳情

在 Jaeger UI 中直觀區分成功/失敗調用鏈。


日志與 Metrics 關聯 📑

TraceContext
OTLP
Metrics
ILogger
OpenTelemetryLogProvider
OTelCollector
LogStore
API
Prometheus
Grafana
  1. 日志

    builder.Logging.AddOpenTelemetry(logging =>logging.AddOtlpExporter());
    
  2. Metrics

    • 自動采集請求計數與時延
    • 自定義 Meter 導出 Prometheus

Jaeger 部署與高可用 🏗?

  • 測試:All-in-One 鏡像,一鍵啟動

  • 生產

    • 組件拆分:Agent/Collector/Query/UI 分離部署
    • 后端存儲:Cassandra / Elasticsearch / Kafka
    • 安全:啟用 TLS、鑒權(mTLS、Token),或通過 OTel Collector 做統一接入與流量控制
    • 多副本:水平擴展與高可用

采樣策略與性能優化 🛡?

收到請求
父 Span 有采樣?
遵從父決策
隨機 < 0.1?
采樣
丟棄
  • ParentBasedSampler:跨服務一致決策
  • Batch 模式:減少網絡與 CPU 開銷
  • 動態調整:環境變量 OTEL_TRACES_SAMPLER / OTEL_TRACES_SAMPLER_ARG
  • 環境差異:開發環境 AlwaysOnSampler;生產環境 5–10%

擴展:OTel Collector & Grafana Tempo 🔗

  • Collector:統一接入、Filter、Auth、轉發至 Jaeger/Tempo/Prometheus
  • Grafana Tempo:專注 Trace 存儲,結合 Prometheus、Loki 構建全棧 Observability

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88726.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88726.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88726.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言中整數編碼方式(原碼、反碼、補碼)

在 C 語言中&#xff0c;原碼、反碼、補碼的運算規則與其編碼特性密切相關&#xff0c;核心差異體現在符號位是否參與運算、進位如何處理以及減法是否能轉化為加法等方面。以下是三者的運算規則及特點分析&#xff08;以 8 位整數為例&#xff0c;符號位為最高位&#xff09;&a…

js二維數組如何變為一維數組

在 JavaScript 中&#xff0c;將二維數組轉換為一維數組&#xff08;扁平化&#xff09;有多種方法&#xff0c;可根據數組結構復雜度、性能需求和兼容性選擇。以下是最常用的實現方式&#xff1a; 1. 使用 flat() 方法&#xff08;ES2019&#xff09; MDN釋義&#xff1a;flat…

Claude code在Windows上的配置流程

前言 昨天在服務器上配置好了 Claude code&#xff0c;發現其編碼性能和效率都非常不錯。 然而&#xff0c;嘗試用它修改帶 UI 界面的客戶端程序時頗為不便&#xff0c;因為服務器沒有圖形化界面&#xff0c;無法直接將應用界面直接顯示到開發機上&#xff0c;調試起來頗為不…

手把手教你用YOLOv10打造智能垃圾檢測系統

無需編程基礎&#xff01;手把手教你用YOLOv10打造智能垃圾檢測系統 垃圾分類不再難&#xff0c;AI助手秒識別 你是否曾站在分類垃圾桶前猶豫不決&#xff1f;塑料瓶是可回收還是其他垃圾&#xff1f;外賣餐盒到底該丟哪里&#xff1f;隨著垃圾分類政策推廣&#xff0c;這樣的困…

batchnorm類

1. 偽代碼&#xff1a;2. python代碼&#xff1a;3. 測試&#xff1a;4. 加深理解&#xff1a;以 為例&#xff0c;x3&#xff0c;可見輸出的batchnorm后y0.2627.查看模型記錄的均值及方差&#xff0c;計算y0.286799&#xff0c;理解是大致這樣的計算過程。&#xff08;為什么數…

SpringBoot項目保證接口冪等的五種方法!

1. 冪等概述 1.1 深入理解冪等性 在計算機領域中&#xff0c;冪等&#xff08;Idempotence&#xff09;是指任意一個操作的多次執行總是能獲得相同的結果&#xff0c;不會對系統狀態產生額外影響。在Java后端開發中&#xff0c;冪等性的實現通常通過確保方法或服務調用的結果…

SQL新手入門詳細教程和應用實例

SQL(Structured Query Language)是用于管理和操作關系型數據庫的標準語言。它允許你創建、查詢、更新和刪除數據。本教程將從基礎概念開始,逐步引導你上手SQL,并提供詳細的應用實例。教程基于標準SQL語法,實際使用時需根據數據庫系統(如MySQL、SQLite或PostgreSQL)調整。…

DVWA-LOW級-SQL手工注入漏洞測試(MySQL數據庫)+sqlmap自動化注入-小白必看(超詳細)

首次使用DVWA的靶場&#xff0c;咋們先從最低級別的LOW開始&#xff0c;因為之前玩過一下墨者學院&#xff0c;對sql注入有一點認識和理解&#xff0c;所以先從sql的盲注開始&#xff1b; 1、測試注入點是否存在sql注入的漏洞&#xff1b; &#xff08;1&#xff09;首先我們…

JAVA線程池詳解+學習筆記

1.線程池基礎概念線程池是一種資源復用技術&#xff0c;通過預先創建并管理一組線程&#xff0c;減少頻繁創建和銷毀線程的開銷。核心思想與數據庫連接池、字符串常量池類似&#xff0c;旨在提升系統性能。核心參數解析ThreadPoolExecutor構造函數包含7個關鍵參數&#xff1a;c…

數據分析庫 Pandas

對于Pandas的簡單認識和基本操作的練習一 介紹 Pandas 是一個開源的數據分析和數據處理庫&#xff0c;它是基于 Python 編程語言的庫。 Pandas 提供了易于使用的數據結構和數據分析工具&#xff0c;特別適用于處理結構化數據&#xff0c;如表格型數據&#xff08;類似于 Excel …

qt 中不要讓 lambda 槽函數捕獲信號源對象的共享指針

錯誤示例std::shared_ptr<QSerialPort> serial{new QSerialPort{}};QSerialPort::connect(serial.get(),&QSerialPort::readyRead,[serial](){QByteArray receive_data serial->readAll();std::cout.write(receive_data.data(), receive_data.size());});這會直接…

Solidity 合約的編寫-完整開發流程:從編譯、測試、部署到交互

&#x1f9f1; Solidity 合約開發全流程&#xff08;Foundry 版&#xff09;? 適合對象&#xff1a;已經能寫合約但不清楚如何測試、部署、交互的開發者? 工具鏈&#xff1a;Foundry&#xff08;forge, anvil, cast&#xff09;&#x1f4cc; 開發流程總覽1?? 初始化項目 2…

設計模式 - 面向對象原則:SOLID最佳實踐

文章目錄深入理解 SOLID&#xff1a;用對原則&#xff0c;別把簡單問題搞復雜SOLID 原則概覽1. 單一職責原則&#xff08;SRP&#xff09;2. 開閉原則&#xff08;OCP&#xff09;3. 里氏替換原則&#xff08;LSP&#xff09;4. 接口隔離原則&#xff08;ISP&#xff09;5. 依賴…

Vue 3 中父組件內兩個子組件相互傳參的幾種方法

方法一&#xff1a;通過父組件中轉&#xff08;Props Emits&#xff09;<!-- ParentComponent.vue --> <template><ChildA :message-from-b"messageFromB" send-to-b"handleSendToB" /><ChildB :message-from-a"messageFromA&q…

三子棋游戲設計與實現(C 語言版)

一、需求分析目標&#xff1a;實現一個簡單的人機對戰三子棋&#xff0c;支持以下功能&#xff1a;初始化空棋盤&#xff0c;清晰展示落子狀態。玩家通過坐標落子&#xff08;X 代表玩家&#xff09;&#xff0c;電腦隨機落子&#xff08;O 代表電腦&#xff09;。實時判斷勝負…

GD32 CAN1和TIMER0同時開啟問題

背景&#xff1a;今天在一個項目調試的時候發現了一些問題&#xff0c;由此貼記錄一下問題解決的過程。使用的芯片是GD32F305VE。使用到了CAN1和TIMER0。在使用這連個外設的時候發送了一些問題。單獨使用CAN1。功能正常。單獨使用TIMER0。配置為輸出模式。功能正常。但是當兩個…

劍指offer56_數組中唯一只出現一次的數字

數組中唯一只出現一次的數字在一個數組中除了一個數字只出現一次之外&#xff0c;其他數字都出現了三次。 請找出那個只出現一次的數字。 你可以假設滿足條件的數字一定存在。 思考題&#xff1a; 如果要求只使用 O(n) 的時間和額外 O(1) 的空間&#xff0c;該怎么做呢&#xf…

從語音識別到智能助手:Voice Agent 的技術進化與交互變革丨Voice Agent 學習筆記

From Research AI&#xff1a; 最近看到 Andrew Ng 的一句話讓我印象深刻&#xff1a;“While some things in AI are overhyped, voice applications seem underhyped right now.”&#xff08;盡管 AI 中有些領域被過度炒作&#xff0c;語音應用卻似乎被低估了&#xff09;。…

什么是Jaccard 相似度(Jaccard Similarity)

文章目錄? 定義&#xff1a;&#x1f4cc; 取值范圍&#xff1a;&#x1f50d; 舉例說明&#xff1a;&#x1f9e0; 應用場景&#xff1a;?? 局限性&#xff1a;&#x1f4a1; 擴展概念&#xff1a;Jaccard 相似度&#xff08;Jaccard Similarity&#xff09; 是一種用于衡量…

ragflow_多模態文檔解析與正文提取策略

多模態文檔解析與正文提取策略 RAGflow的文檔解析系統位于deepdoc/parser/目錄下,實現了對多種文檔格式的統一解析處理。該系統采用模塊化設計,針對不同文檔格式提供專門的解析器,并通過視覺識別技術增強解析能力。本文將深入探討RAGflow的文檔解析系統的設計原理、實現細節…