.NET 项目集成可观测性:从架构思考到落地实践
本文基于一个真实的.NET 9项目集成可观测性栈的经历分享从为什么做到怎么落地的完整过程。一、为什么需要集成可观测性1.1 触发点一个慢接口项目中有一个业务接口涉及多表关联、缓存查询、外部服务调用业务联链条很长。上线后用户反馈慢但具体慢在哪一步是数据库查询是外部调用还是序列化靠日志很难定位本地复现也困难。我的诉求很简单想上好监控做到心里有数。接口整体耗时多少哪些步骤最耗时系统运行时的QPS、错误率、内存、CPU是什么水平出问题时能快速定位而不是靠猜。这就是我们集成可观测性的起点——不是为了高大上而是为了解决一个具体的问题。二、可观测性架构设计此次集成用到的核心组件有4个OpenTelemetry,Prometheus,jaeger,grafana在这之前日志的部分我们已经集成到了ELK所以整个可观测性的架构设计图如下组件作用说明OpenTelemetry Collector数据中枢接收应用推来的 OTLP 数据分发给后端Prometheus指标存储存 QPS、延迟、内存等时序数据Jaeger链路追踪存每次请求的完整调用链Grafana可视化把Prometheus和Jaeger的数据做成图表ElasticSearch日志存储通过Logstash将系统产生的各类日志传输存储注意本篇后续不过多涉及ELK相关内容这里点出来是因为和可观测性组件产生了交集。此外本文演示的相关中间件的部署环境都是基于Windows大家部署时可以根据实际情况选择部署环境。*2.1 部署架构我这里的数据可观测组件部署情况是只在1台中心服务器上部署了JaegerPrometheus和Grafana而所有应用节点服务器都通过Otel将数据推送到中心服务器也就是webapi的trace/metric全部汇聚到中心服务器只提供一个面板地址同一排查。这套架构在我这里的场景验证是有效的适合中小型项目。2.2 OpenTelemetry Collector数据中枢Collector是整个栈的核心枢纽应用只跟它通信它负责把数据分发给Prometheus和Jaeger。核心配置receivers:otlp:protocols:grpc:endpoint:0.0.0.0:4317# 应用通过这个端口推数据过来processors:batch:timeout:5s# 攒批超时减少网络开销memory_limiter:limit_mib:512# 防止数据堆积导致OOMexporters:prometheus:endpoint:0.0.0.0:8889# 暴露给Prometheus抓取otlp/jaeger:endpoint:127.0.0.1:14250# traces推给Jaegertls:insecure:true# 内网不需要TLSservice:pipelines:metrics:receivers:[otlp]exporters:[prometheus]traces:receivers:[otlp]exporters:[otlp/jaeger]关键点receivers定义数据怎么进来OTLP gRPCexporters定义数据往哪去Prometheus收指标Jaeger收tracesprocessors做批量和内存保护注意不要加namespace前缀否则Grafana查询metric名会不匹配2.3 Prometheus指标存储Prometheus 定时去 OTel Collector 拉数据pull 模式。核心配置global:scrape_interval:15s# 每 15 秒抓一次scrape_configs:-job_name:otel-collectorstatic_configs:-targets:[localhost:8889]# Collector的Prometheus exporter端口启动参数prometheus.exe--config.fileprometheus.yml--storage.tsdb.retention.time30dretention.time30d数据保留 30 天自动清理2.4 Jaeger链路追踪Jaeger负责存储和查询traces可以看到每次请求的完整调用链。核心配置Jaeger v2格式receivers:otlp:protocols:grpc:endpoint:0.0.0.0:14250# 接收 Collector 推送的 tracesexporters:jaeger_storage_exporter:# 写入存储必须否则UI为空trace_storage:jaeger_storageextensions:jaeger_query:# Web UIstorage:traces:jaeger_storagejaeger_storage:# 内存存储后端backends:jaeger_storage:memory:max_traces:100000service:pipelines:traces:receivers:[otlp]exporters:[jaeger_storage_exporter]# 必须包含踩坑提醒traces pipeline必须包含jaeger_storage_exporter否则Jaeger UI里Service下拉为空这是最常见的坑。2.5 Grafana可视化Grafana负责把数据做成图表配置两个数据源即可datasources:-name:Prometheustype:prometheusurl:http://localhost:9090isDefault:true-name:Jaegertype:jaegerurl:http://localhost:16686部署顺序很重要1. Jaeger ← 必须先启动Collector 要连它的 14250 2. OTel Collector ← 接收应用数据 3. Prometheus ← 抓取指标 4. Grafana ← 可视化上述服务部署后控制台输出效果分别如下jaeger服务启动后控制台输出启动Otel Collector后传输数据效果如下启动Prometheus后控制台输出效果如下grafana启动后控制台输出三、项目代码3.1 和OpenTelemetry通信.NET项目里只需要做一件事通过OTel SDK把数据推给OTel Collector。后面的Prometheus、Jaeger、Grafana都是接收和展示不需要应用关心。NuGet 包PackageReferenceIncludeOpenTelemetry.Extensions.HostingVersion1.15.3/PackageReferenceIncludeOpenTelemetry.Instrumentation.AspNetCoreVersion1.15.2/PackageReferenceIncludeOpenTelemetry.Instrumentation.RuntimeVersion1.15.1/PackageReferenceIncludeOpenTelemetry.Exporter.OpenTelemetryProtocolVersion1.15.3/服务注册约 30 行代码privatestaticvoidConfigureOpenTelemetry(thisWebApplicationBuilderbuilder){stringotlpEndpointbuilder.Configuration[OTEL_EXPORTER_OTLP_ENDPOINT]??http://localhost:4317;builder.Services.AddOpenTelemetry().WithTracing(tracing{tracing.AddAspNetCoreInstrumentation()// 自动采集HTTP请求traces.AddSource(Declaration.*)// 通配自定义Span.ConfigureResource(rr.AddService(Magic.Declaration.WebAPI)).AddOtlpExporter(options{options.EndpointnewUri(otlpEndpoint);options.ExportProcessorTypeExportProcessorType.Batch;});}).WithMetrics(metrics{metrics.AddAspNetCoreInstrumentation()// 自动采集HTTP请求指标.AddRuntimeInstrumentation()// .NET运行时指标GC、CPU、内存.ConfigureResource(rr.AddService(Magic.Declaration.WebAPI)).AddOtlpExporter(options{options.EndpointnewUri(otlpEndpoint);});});}采集信息类别类别指标说明HTTP 请求QPS、延迟分布、状态码Instrumentation.AspNetCore自动采集.NET 运行时GC、CPU、内存、线程池Instrumentation.Runtime自动采集3.2 开发环境为了保持开发环境的高效且能看到采集到的基本数据我们可以在开发环境配置将采集的数据输出到控制台。if(builder.Environment.IsDevelopment()){tracing.AddConsoleExporter();// traces 输出到控制台}启动应用后控制台会直接输出每次请求的 trace 信息Activity.TraceId: 8d35e... Activity.SpanId: a7f2e... Activity.DisplayName: GET /api/order/detail Activity.Kind: Server Activity.Duration: 00:00:00.1234 Resource associated with Activity: service.name: MyApp.WebAPI效果如下开发阶段用控制台就够了不用装任何额外组件。3.3 可拔插设计这套可观测性栈是锦上添花型接入不是项目运行的必要条件不装 OTel Collector应用正常跑只是不采集数据不装 Prometheus/JaegerCollector 可以只做控制台输出环境变量不配代码里有默认值http://localhost:4317对业务代码零侵入所有配置都收敛在服务注册阶段业务代码不需要任何改动。四、怎么验证和分析采集到的数据4.1 验证数据流部署完成后先验证数据是否流通# 1. 检查 Collector 是否在接收数据curlhttp://localhost:8888/metrics|findstraccepted_spans# 2. 检查 Prometheus 是否有指标curlhttp://localhost:9090/api/v1/query?queryhttp_server_request_duration_seconds_count# 3. 检查 Jaeger 是否有 tracescurlhttp://localhost:16686/api/services4.2 Jaeger链路追踪分析Jaeger UI地址http://localhost:16686定位链条打开Jaeger面板后点击某条Trace展开看完整的调用链[HTTP GET /api/order/detail] 120ms ├── [MyApp.CreateOrder] 95ms ← 你的自定义 Span │ ├── [FreeSql Query] 80ms ← 数据库查询 │ └── [Redis Get] 5ms ← 缓存读取 └── [HTTP Response] 10msTips链路追踪数据除了在Jaeger面板查看也可以集成到Grafana统一管理本篇受篇幅限制不在赘述下面分别给出Jaeger和Grafana的面板效果。jaeger面板grafana面板常见场景场景操作接口慢但不知道慢在哪搜该接口的Trace → 看哪个Span耗时最长间歇性超时搜Duration 1s的Trace → 对比正常和异常的差异500 错误搜Status ERROR的Trace → 看Logs中的异常信息4.3 Grafana配置DashboardGrafana UI地址http://localhost:3000第一步添加数据源如果用 provisioning 文件部署则自动配置Configuration → Data Sources → Add data source → 选 Prometheus 和 Jaeger第二步创建 Dashboard推荐先建一个包含以下面板的Dashboard面板数据源PromQL实时QPSPrometheussum(rate(http_server_request_duration_seconds_count[1m]))P95延迟Prometheushistogram_quantile(0.95, sum(rate(http_server_request_duration_seconds_bucket[5m])) by (le))错误率Prometheussum(rate(http_server_request_duration_seconds_count{http_response_status_code~5..}[5m])) / sum(rate(http_server_request_duration_seconds_count[5m]))内存占用Prometheusdotnet_gc_last_collection_heap_size_bytesCPU使用率Prometheusrate(dotnet_process_cpu_time_seconds_total[1m])第三步按路由分组想看每个接口的独立指标用by (http_route)分组sum(rate(http_server_request_duration_seconds_count[5m])) by (http_route, http_request_method)Dashboard 设计原则顶部放概览数字QPS、延迟、错误率、CPU中间放趋势图按时间变化底部放明细表按接口分组Grafana效果注意以上统计的方法均可在Grafana社区官网查询到也可以在这里https://grafana.com/grafana/dashboards/查询一些模板直接套用。还可以直接把你的需求告诉你的智能体助手。五、总结集成可观测性的本质是让系统运行状态可见而不是靠猜。四个组件各司其职OpenTelemetry Collector 做数据中枢Prometheus 存指标Jaeger 存链路Grafana 做展示.NET 项目要做的很少接入 OTel SDK配置 OTLP 导出地址自动采集 HTTP 请求和运行时指标需要时加自定义 Span 定位业务逻辑开发阶段控制台就能看生产环境按需部署可拔插、零侵入不装组件不影响业务运行配置都在服务注册阶段业务代码无感环境变量控制接入程度可观测性不是一次性任务而是持续的过程——先跑起来遇到问题再逐步深入。

相关新闻

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果

终极AI换脸指南:如何用roop-unleashed实现电影级面部替换效果 【免费下载链接】roop-unleashed Evolved Fork of roop with Web Server and lots of additions 项目地址: https://gitcode.com/gh_mirrors/ro/roop-unleashed 在数字创意领域,AI换脸…

2026/7/8 7:49:27 阅读更多 →
腾讯混元Hy3技术拆解:295B MoE架构、定价策略与Benchmark实测对比

腾讯混元Hy3技术拆解:295B MoE架构、定价策略与Benchmark实测对比

核心结论 腾讯于2026年7月6日正式发布混元Hy3,这是一个总参数295B、激活参数21B的MoE架构模型(192专家、每次激活Top-8),支持256K上下文窗口。本文从架构设计、定价策略、Benchmark实测三个维度进行技术拆解,并与GPT-5…

2026/7/8 7:49:27 阅读更多 →
3个关键步骤实现Mac NTFS完全读写:开源工具Free-NTFS-for-Mac的终极解决方案

3个关键步骤实现Mac NTFS完全读写:开源工具Free-NTFS-for-Mac的终极解决方案

3个关键步骤实现Mac NTFS完全读写:开源工具Free-NTFS-for-Mac的终极解决方案 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounti…

2026/7/8 7:49:27 阅读更多 →

最新新闻

LSKNet 大选择性核注意力 PyTorch 实现:遥感目标检测 3 大基准 SOTA 复现

LSKNet 大选择性核注意力 PyTorch 实现:遥感目标检测 3 大基准 SOTA 复现

LSKNet大选择性核注意力:遥感目标检测的PyTorch实战指南在遥感图像分析领域,微小目标的精确检测一直是个棘手难题。传统方法往往受限于固定尺度的感受野,难以同时处理不同尺寸和复杂背景的目标。本文将深入解析LSKNet(Large Selec…

2026/7/8 8:49:46 阅读更多 →
GEO 工具怎么选:AI 可见度监测、AI 心智审计、长效运营闭环不是一回事

GEO 工具怎么选:AI 可见度监测、AI 心智审计、长效运营闭环不是一回事

开篇导语2026 年生成式引擎优化(GEO)赛道工具层出不穷,但绝大多数企业都陷入同一个误区:混淆单次品牌体检、短期关键词监测、长效 AI 心智运营、品牌风险审计四类核心需求。市面上主流工具 GEO 探针、AllrightTOP、AiSaysTOP 功能…

2026/7/8 8:47:45 阅读更多 →
快速提升网站权重 www.xssdgy.cn

快速提升网站权重 www.xssdgy.cn

提升网站权重并非一蹴而就,而是一项需要耐心和持续投入的系统工程。根据行业经验,一个新站通常需要3到6个月甚至更长时间的持续优化,才能看到权重的显著提升。针对 www.xssdgy.cn 这个网站,可以从以下几个核心方面入手&#xff1a…

2026/7/8 8:47:45 阅读更多 →
webpack:前端打包领域的老牌基建

webpack:前端打包领域的老牌基建

文章目录webpack:前端打包领域的老牌基建webpack:前端打包领域的老牌基建 webpack 在 GitHub 上拿到了 65,834 颗 Star,是前端工程化绕不开的一块基础设施。 webpack 是一个模块打包工具。它最初的目标是把 JavaScript 文件打包成浏览器可用…

2026/7/8 8:43:43 阅读更多 →
原神成就一键导出工具:YaeAchievement终极指南

原神成就一键导出工具:YaeAchievement终极指南

原神成就一键导出工具:YaeAchievement终极指南 【免费下载链接】YaeAchievement 更快、更准的原神数据导出工具 项目地址: https://gitcode.com/gh_mirrors/ya/YaeAchievement 还在为原神成就数据导出而烦恼吗?YaeAchievement作为一款专为原神玩家…

2026/7/8 8:41:42 阅读更多 →
PyTorch 1.13 多框架随机种子设置:Python/Numpy/TensorFlow 5行代码统一控制

PyTorch 1.13 多框架随机种子设置:Python/Numpy/TensorFlow 5行代码统一控制

PyTorch 1.13 多框架随机种子统一控制:5行代码实现全局可复现性在机器学习项目中,实验结果的可复现性一直是开发者面临的核心挑战之一。当项目同时涉及Python标准库、NumPy、PyTorch和TensorFlow等多个框架时,每个框架独立的随机数生成机制会…

2026/7/8 8:39:42 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻