架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 21|回复: 0

[ASP.NET] ASP.NET Core(三十四)Trace Context 追踪上下文(链路追踪)

[复制链接]
发表于 8 小时前 | 显示全部楼层 |阅读模式
需求:在微服务架构中,在遇到问题的时候,往往非常难以排查,不知道是那个服务抛出的异常,可能是该服务写的有BUG,或者调用该服务的服务传递的信息有问题。如果可以记录所有请求的上下文,也就是记录整个完整事务请求的链路,对排除和分析问题显得至关重要。

回顾:
ASP.NET Core 链路追踪(二)使用 SkyAPM 集成
https://www.itsvse.com/thread-9458-1-1.html

ASP.NET Core 链路追踪(四)接入 Jaeger 链路追踪
https://www.itsvse.com/thread-9537-1-1.html

异常 stack trace 对于目标是单进程的应用程序来说非常适合,比如单体应用系统。但是反过来说,对于处理分布式应用系统,例如微服务架构,stack trace 就不能足够用来展示整体的消息追踪了。这就是为什么分布式追踪工具和标准变得必要的原因。W3C 定义了这种追踪类型的标准,称为 Trace Context。

Trace Context 标准

W3C Trace Context 文档:超链接登录可见。

W3C Trace Context 规范定义了针对 HTTP 头的标准和格式,用来传播分布式追踪上下文信息。其中定义了 2 个字段用来在 HTTP 请求头中传播追踪流。先看一下标准定义中的这 2 个字段:

  • traceparent: 用来描述在追踪图谱中到达请求的位置。它表示在追踪系统中到达请求的通用格式,被所有的 vendor 所理解。
  • tracestate: 使用 vendor 特定的数据表示形式来扩展 traceparent,使用 name/value 对形式。在 tracestate 中保存信息是可选的。

traceparent 字段

traceparent 字段的规范使用扩充巴科斯范式 (ABNF ) 形式定义,由 4 个部分组成:
version - traceid - parentid/spanid - traceflags

例如:
00-480e22a2781fe54d992d878662248d94-b4b37b64bb3f6141-00

  • version: 8 位,系统适配的追踪上下文版本,当前位 00
  • trace-id: 16 字节,追踪整体的标识。用于在系统中标识一个分布式追踪整体,同一个链路中,该值一模一样
  • parent-id/span-id: 8 字节,用来表述在进入请求中,或者对外请求中,当前跨度的父级。
  • trace-flags: 8 位,调用者的建议标志,可以考虑为调用者的建议,限制为 3 个原因:信息或是滥用,调用方的错误,或者在调用方与被调用方的不同负载。

所有字段都使用 16 进制编码 ( hexadecimal ),如下图:

QQ截图20251222092435.jpg

.NET 分布式跟踪

分布式跟踪是一种诊断技术,可帮助工程师本地化应用程序中的故障和性能问题,尤其是可能分布在多台计算机或进程中的故障和性能问题。 此技术通过应用程序中的请求跟踪,将不同应用程序组件完成的工作关联在一起,并从应用程序在处理并发请求时可能执行的其他工作中分离出来。 例如,负载均衡器可能首先收到对典型 Web 服务的请求,然后转发到 Web 服务器进程,然后向数据库发出多个查询。 使用分布式跟踪,工程师可以区分这些步骤是否失败、每个步骤花费的时间,以及每个步骤运行时可能记录的消息。

在 .NET 中 System.Diagnostics.Activity 库已经被配置为使用 W3C 标准。W3C 风格的 traceparent 标头 Request-Id 标头是在 ASP.NET Core 2.0 中添加的。要将其更改为符合 W3C Trace Context 的 traceparent 标头,请在启动程序时将 Activity.DefaultIdFormat 静态属性设置为 W3C。代码如下:
测试流程,浏览器 -> A 服务(/http,后端使用 HttpClient 再请求 B 服务)接口 -> B 服务(/test)接口,A 服务输出自己的 Trace Context 和 B 服务的 Trace Context,代码如下:
启动 A、B 服务,如下图:

QQ截图20251222093541.jpg

浏览器打开A服务,如下图:

QQ截图20251222094116.jpg
Id: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: bd06e8d507a43f42
ParentId:

响应内容:{"id":"00-9891603e6c4921598951f425d98e4df7-8874f9b2f9c0702e-00","traceId":"9891603e6c4921598951f425d98e4df7","spanId":"8874f9b2f9c0702e","parentId":"00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00","traceFlags":"None","isSampled":false}

--------------------------------------------------
Name: HttpHandlerDiagnosticListener
DateTime: 2025/12/22 9:37:22
Id: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: e0336cc56a4f2150
ParentId: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00

Key: System.Net.Http.HttpRequestOut.Stop, Value: { Response = StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Date: Mon, 22 Dec 2025 01:37:21 GMT
  Server: Kestrel
  Transfer-Encoding: chunked
  Connection: keep-alive
  Content-Type: application/json; charset=utf-8
}, Request = Method: GET, RequestUri: 'http://localhost.charlesproxy.com:5551/test', Version: 1.1, Content: <null>, Headers:
{
  traceparent: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00
}, RequestTaskStatus = RanToCompletion }
--------------------------------------------------
使用 Charles Proxy 抓包工具,请求和响应如下图:

QQ截图20251222095151.jpg

如果想禁用 HttpClient 传递 traceparent,环境变量设置如下:

参考:

超链接登录可见。
超链接登录可见。
超链接登录可见。
超链接登录可见。
超链接登录可见。
超链接登录可见。




上一篇:010 Editor 默认没自带 DEX 模板
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2025-12-22 18:40

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表