Jaeger Deployment

Page content

什么是 Jaeger

Jaeger 是基于 OpenTracing 规范的实现,由 Uber 推出的一款开源分布式追踪系统,它由三部分组成。

  • Agent

和业务系统部署在一台服务器上,负责接收由业务系统发出的数据,并批量发送给 Collector

  • Collector

用于接收各 Agent 发送来的数据,存入数据库,Jaeger 支持 Elasticsearch 和 Cassandra,这里我选择了前者

  • Query

通过 UI 展示数据,依赖于 Collector

部署

我在测试环境利用 docker-compose 临时搭建了 Jaeger,下面是我的 docker-compose.yml 文件

 1version: "3"
 2
 3services:
 4    jaeger-collector:
 5        image: jaegertracing/jaeger-collector:1.13
 6        ports:
 7            - "14269:14269"
 8            - "14268:14268"
 9            - "14267:14267"
10            - "9411:9411"
11        networks:
12            - jaeger
13        restart: on-failure
14        environment:
15            - SPAN_STORAGE_TYPE=elasticsearch
16        command: [
17            "--es.server-urls=${ES_SERVER_URLS}",
18        ]
19
20    jaeger-agent:
21        image: jaegertracing/jaeger-agent:1.13
22        ports:
23            - "5775:5775/udp"
24            - "6831:6831/udp"
25            - "6832:6832/udp"
26            - "5778:5778"
27        networks:
28            - jaeger
29        restart: on-failure
30        environment:
31            - SPAN_STORAGE_TYPE=elasticsearch
32        depends_on:
33            - jaeger-collector
34        command: [
35            "--collector.host-port=jaeger-collector:14267"
36        ]
37
38    jaeger-query:
39        image: jaegertracing/jaeger-query:1.13
40        environment:
41            - SPAN_STORAGE_TYPE=elasticsearch
42        ports:
43            - "16686:16686"
44            - "16687:16687"
45        networks:
46            - jaeger
47        restart: on-failure
48        command: [
49            "--es.server-urls=${ES_SERVER_URLS}"
50        ]
51
52networks:
53    jaeger:
54        driver: bridge

由于我的 es 是部署在其他服务器上,所以添加一个 .env 文件

1ES_SERVER_URLS=http://es-host:9200

在浏览器里打开 http://jaeger-ui:16686 可以看到效果

jaeger-ui-screenshot

在 ASP.NET Core 项目中使用 Jaeger

首先引用两个 nuget

项目全局设置

在 Startup.cs 的 ConfigureServices 中添加以下代码

 1services.AddOpenTracing();
 2services.Configure<GenericEventOptions>(config =>
 3{
 4    // 忽略多余的日志,否则每次请求的日志会太多
 5    config.IgnoreAll = true;
 6});
 7services.AddSingleton<ITracer>(serviceProvider =>
 8{
 9    string serviceName = serviceProvider.GetRequiredService<IHostingEnvironment>().ApplicationName;
10    var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
11    var sampler = new ConstSampler(true);
12    var reporter = new RemoteReporter.Builder()
13        .WithLoggerFactory(loggerFactory)
14        // 如果业务系统服务器上部署了 Jaeger Agent,这个地址应该写localhost
15        .WithSender(new UdpSender("jaeger-agent-host", 6831, 0))
16        .Build();
17    var tracer = new Tracer.Builder(serviceName)
18        .WithLoggerFactory(loggerFactory)
19        .WithSampler(sampler)
20        .WithReporter(reporter)
21        .Build();
22    GlobalTracer.Register(tracer);
23    return tracer;
24});

在方法中使用

首先需要依赖注入 ILoggerFactory 并创建一个 ILogger 对象

1private readonly ILogger<TestController> _logger;
2
3public TestController(ILoggerFactory loggerFactory)
4{
5    this._logger = loggerFactory.CreateLogger<TestController>();
6}

然后在需要打日志的地方

1_logger.LogDebug($"log something");

总结

Jaeger 能够满足微服务下的分布式链路追踪需求,而且支持自定义的日志记录,且部署上也较为方便。美中不足的是 UI 缺少接口访问的相关指标统计,还有相比现在较火的 Skywalking,Jaeger 缺少服务告警的功能,不过由于都是 RESTful 的接口,所以完全可以自己再撸一套界面。