在微服务架构普及的当下,一个用户请求往往会经过多个独立部署的服务处理,服务间的调用关系错综复杂。当请求出现超时或报错等问题时,仅靠单个服务的日志很难快速定位根因,这时候分布式追踪系统就派上了用场。Jaeger 就是这类系统中应用广泛的开源方案,它能够帮助开发者清晰地还原请求的完整生命周期。

Jaeger 的核心概念与架构解析
Jaeger 最初由 Uber 开源,如今已经是云原生计算基金会(CNCF)的毕业项目。它主要用于监控和排查微服务架构下的分布式事务,支持分布式上下文传播、服务依赖分析、性能优化以及故障定位等核心能力。通过 Jaeger,开发者和运维人员可以直观地看到一个请求在各个微服务节点之间的流转过程,从而快速发现性能瓶颈或错误节点。
Jaeger 的追踪逻辑建立在两个核心概念之上,即 Trace 和 Span。一个 Trace 代表一次完整的请求链路,它由多个 Span 组合而成。每个 Span 则代表链路中的一个独立操作单元,例如一次外部服务调用、一次数据库查询或一段复杂的业务逻辑计算。Span 之间通过特定的上下文信息进行关联,最终形成一棵完整的调用树,清晰地展示了请求的执行路径和时间消耗。
为了实现高效的分布式追踪,Jaeger 设计了四个核心组件。首先是 Client,它是嵌入到业务服务中的 SDK,负责生成追踪数据,支持包括 .NET、Java、Go 在内的多种编程语言。其次是 Agent,它作为常驻服务节点,负责接收 Client 上报的追踪数据并批量转发给 Collector,通常与微服务部署在同一台机器上以降低网络开销。接着是 Collector,它接收 Agent 上报的数据,进行校验、处理和存储,支持将数据持久化到 Elasticsearch 或 Cassandra 等存储组件中。最后是 Query 组件,它提供查询接口和 Web UI,用户可以通过界面查看调用链路、服务依赖和请求耗时等详细信息。
在 .NET 微服务中集成 Jaeger 的实战指南
在 .NET 微服务中集成 Jaeger,我们通常会结合 OpenTelemetry 来上报追踪数据。OpenTelemetry 作为云原生可观测性的标准,提供了统一的 API 和 SDK,使得应用无需直接依赖 Jaeger 的特定客户端,从而保证了后续切换追踪系统的灵活性。首先,我们需要部署 Jaeger 服务,在开发和测试环境中,最简单的方式是使用 Docker 启动 All-in-one 版本。
docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14250:14250 -p 14268:14268 -p 14269:14269 -p 9411:9411 ghcr.io/jaegertracing/all-in-one:1.47
环境准备就绪后,需要在 .NET 微服务项目中引入必要的依赖。如果是 .NET 6 及以上版本,可以直接在项目文件中添加 OpenTelemetry 相关的 NuGet 包引用。这些包包括提供宿主扩展的 OpenTelemetry.Extensions.Hosting、自动采集 ASP.NET Core 请求数据的 OpenTelemetry.Instrumentation.AspNetCore、采集 HttpClient 调用数据的 OpenTelemetry.Instrumentation.Http,以及将数据导出到 Jaeger 的 OpenTelemetry.Exporter.Jaeger。
<ItemGroup> <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.5.0" /> </ItemGroup>
依赖引入完成后,便可以在项目的入口文件中配置 OpenTelemetry 以将追踪数据上报至 Jaeger。通过配置 TracerProvider,我们可以设置服务名称、启用自动采集功能,并指定 Jaeger 导出器的目标地址。
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
// 配置OpenTelemetry追踪
builder.Services.AddOpenTelemetry()
.WithTracing(tracerProvider =>
{
tracerProvider
// 设置服务名称,会在Jaeger中显示
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("OrderService"))
// 自动采集ASP.NET Core请求数据
.AddAspNetCoreInstrumentation()
// 自动采集HttpClient调用数据
.AddHttpClientInstrumentation()
// 配置Jaeger导出器
.AddJaegerExporter(options =>
{
// Jaeger Agent的地址,默认UDP端口6831
options.AgentHost = "127.0.0.1";
options.AgentPort = 6831;
// 也可以配置Collector的HTTP地址,默认端口14268
// options.Endpoint = new Uri("http://127.0.0.1:14268/api/traces");
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
在微服务架构中,服务间的相互调用是常态。如果微服务之间使用 HttpClient 进行通信,OpenTelemetry 会自动传播追踪上下文,开发者无需进行额外的手动处理。这种自动传播机制确保了跨服务的调用链路能够被完整地串联起来。
[ApiController]
[Route("api/order")]
public class OrderController : ControllerBase
{
private readonly HttpClient _httpClient;
public OrderController(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
[HttpGet("{orderId}")]
public async Task<IActionResult> GetOrder(string orderId)
{
// 调用用户服务,追踪上下文会自动传递
var userResponse = await _httpClient.GetAsync("http://127.0.0.1:5001/api/user/123");
var userInfo = await userResponse.Content.ReadAsStringAsync();
return Ok(new { OrderId = orderId, UserInfo = userInfo });
}
}
追踪结果分析与生产环境最佳实践
当多个微服务启动并产生交互后,开发者可以通过访问 Jaeger 的 Web UI 来查看追踪结果。在界面的 Service 下拉框中选择对应的服务名称并点击查找,即可获取对应的 Trace 列表。点击单个 Trace,系统会展示完整的调用链路,包括每个 Span 的具体耗时、附加标签以及日志信息,同时还能直观地呈现出服务之间的依赖拓扑关系,这对于排查复杂系统的性能瓶颈至关重要。
虽然 All-in-one 版本在开发测试阶段非常便捷,但在生产环境中,强烈建议部署独立的 Jaeger Collector 和底层存储组件,以确保系统的高可用性和数据的安全性。此外,由于全量采样会产生庞大的追踪数据,容易占用过多的存储空间和网络带宽,因此需要通过配置合理的采样策略来控制追踪数据的上报比例,从而在可观测性与系统资源消耗之间取得平衡。
除了依赖框架自动采集的 Span 之外,开发者还可以在业务代码中手动创建 Span,以记录自定义的关键操作。例如,针对一段复杂的业务逻辑,可以手动开启一个 Span,并为其添加特定的属性标签或记录异常信息。这种精细化的追踪方式能够帮助团队更深入地理解业务代码的执行细节,进一步提升故障排查的效率。
using var span = TracerProvider.Default.GetTracer("OrderService").StartActiveSpan("ProcessOrder");
try
{
// 执行业务逻辑
span.SetAttribute("order.id", orderId);
}
catch (Exception ex)
{
// 记录异常信息并设置状态
span.RecordException(ex);
span.SetStatus(Status.Error);
}
分布式追踪是现代微服务架构中不可或缺的可观测性基石。通过深入理解 Jaeger 的核心原理,并结合 OpenTelemetry 在 .NET 微服务中进行规范化集成,开发团队能够构建起透明、高效的监控体系。在未来的系统演进中,建议持续关注可观测性标准的更新,不断优化采样策略与自定义追踪逻辑,从而为微服务系统的稳定运行保驾护航。
Jaeger.NET_微服务分布式追踪OpenTelemetry修改时间:2026-06-19 05:54:33