在 .NET 微服务中集成 Jaeger 链路跟踪可以帮助你监控和分析服务之间的调用关系和性能瓶颈。下面是实现步骤和示例代码:
1. 安装必要的 NuGet 包
需要安装以下包到每个微服务项目中:
OpenTelemetry.Extensions.Hosting
OpenTelemetry.Instrumentation.AspNetCore
OpenTelemetry.Exporter.Jaeger
2. 配置 Jaeger 链路跟踪
在 Program.cs
中添加 Jaeger 配置:
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
// 添加服务
builder.Services.AddControllers();
// 配置 Jaeger 链路跟踪
builder.Services.AddOpenTelemetryTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
// 设置服务资源信息
.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService(serviceName: builder.Environment.ApplicationName,
serviceVersion: "1.0.0"))
// 启用 ASP.NET Core instrumentation
.AddAspNetCoreInstrumentation()
// 启用 HttpClient instrumentation (用于跟踪服务间调用)
.AddHttpClientInstrumentation()
// 配置 Jaeger 导出器
.AddJaegerExporter(options =>
{
// Jaeger 服务地址,默认端口是 6831
options.AgentHost = "localhost";
options.AgentPort = 6831;
// 可选:配置服务名称(如果未通过 ResourceBuilder 设置)
// options.ServiceName = builder.Environment.ApplicationName;
});
});
var app = builder.Build();
// 中间件配置
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
3. 手动创建自定义跨度(Span)
如果需要跟踪特定的代码块,可以手动创建跨度:
using Microsoft.AspNetCore.Mvc;
using OpenTelemetry.Trace;
namespace JaegerDemo.Controllers;
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
private readonly Tracer _tracer;
private readonly HttpClient _httpClient;
public WeatherForecastController(
ILogger<WeatherForecastController> logger,
Tracer tracer,
HttpClient httpClient)
{
_logger = logger;
_tracer = tracer;
_httpClient = httpClient;
}
[HttpGet(Name = "GetWeatherForecast")]
public async Task<IEnumerable<WeatherForecast>> Get()
{
// 创建自定义跨度
using var customSpan = _tracer.StartActiveSpan("CustomWeatherProcessing");
try
{
// 添加自定义标签
customSpan.SetAttribute("location", "Beijing");
// 调用其他服务(会自动被跟踪)
var response = await _httpClient.GetAsync("https://api.example.com/weather");
response.EnsureSuccessStatusCode();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
catch (Exception ex)
{
// 记录错误到跨度
customSpan.RecordException(ex);
customSpan.SetStatus(Status.Error);
throw;
}
}
}
4. 启动 Jaeger 服务
可以使用 Docker 快速启动 Jaeger:
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 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.47
启动后,访问 http://localhost:16686
可以打开 Jaeger UI 查看跟踪数据。
5. 关键配置说明
ServiceName
:每个微服务应该有唯一的服务名,便于在 Jaeger UI 中区分AgentHost
和AgentPort
:Jaeger Agent 的地址,默认是localhost:6831
- 自动 instrumentation 会跟踪:
- HTTP 请求(ASP.NET Core)
- HttpClient 调用
- 数据库操作(需额外安装对应 instrumentation 包)
通过这种方式,你可以实现 .NET 微服务的分布式链路跟踪,帮助诊断跨服务调用中的问题。