1. Jaeger介绍
Jaeger 受 Dapper 和 OpenZipkin 的启发,是由 Uber Technologies 发布的开源分布式追踪系统。它用于监控和排查
基于微服务的分布式系统问题,包括:
- 分布式上下文传播
- 分布式事务监控
- 根因分析
- 服务依赖关系分析
- 性能 / 延迟优化
Jaeger 架构:
整体上讲,一个基础的 Jaeger 追踪系统包含下面几个部分:
- jaeger-query: 用于客户端查询和检索组件,并包含了一个基础的 UI
- jaeger-collector: 接收来自 jaeger-agent 的 trace 数据,并通过处理管道来执行。当前的处理管道包含验证 trace 数据,创建索引,执行数据转换以及将数据存储到对应的后端
- jaeger-agent: 一个网络守护进程,侦听通过 UDP 发送的 spans ,它对其进行批处理并发送给收集器。它被设计为作为基础设施组件部署到所有主机。代理将收集器的路由和发现从客户机抽象出来
- backend-storage: 用于指标数据存储的可插拔式后端存储,支持 Cassandra, Elasticsearch and Kafka
- ingester: 可选组件,用于从 kafka 中消费数据并写入到可直接读取的 Cassandra 或 Elasticsearch 存储中
注意:
trace 和 span 是链路追踪系统中的专业属于,span 就表示具体的一个工作单元,并且包含了该单元的元数据比如具体是什么操作,执行的时间等等,而 trace 是通过整个系统的数据路径,可以被认为是将 Spans 组成一个有向无环图 (DAG)
当前Jaeger的SDK支持有如下:
--官方
1.Go
2.Java
3.Node
4.Python
5.C++
--非官方
1.PHP
3.Others
2.Jaeger All in one部署
如果只是为快速感受使用Jaeger,Jaeger直接提供一个All in one的docker镜像,通过All in one的image,我们可以通过以下命令直接启动一套完整的Jaeger tracing系统:
docker run -d -e \
COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
一旦启动成功后,就可以去http://localhost:16686看到Jaeger UI了,如下所示。
注:在All in one模式下,Data Store使用的是内存,因此若重启dockre容器后就看不到之前的数据了。所以,该模式仅可用于前期demo或者验证,不可在生产环境中这样部署。
通过上述All in one启动方式,我们直接发现了Jaeger启动时占据了很多端口,当然,并不是所有的端口都是必需的,这儿简单列出这些端口的说明如下:
端口 协议 所属模块 功能
5775 UDP agent 通过兼容性Thrift协议,接收Zipkin thrift类型数据
6831 UDP agent 通过兼容性Thrift协议,接收Jaeger thrift类型数据
6832 UDP agent 通过二进制Thrift协议,接收Jaeger thrift类型数据
5778 HTTP agent 配置控制服务接口
16686 HTTP query 客户端前端界面展示端口
14268 HTTP collector 接收客户端Zipkin thrift类型数据
14267 HTTP collector 接收客户端Jaeger thrift类型数据
9411 HTTP collector Zipkin兼容endpoint
3. Sampling
关于Jaeger系统中的采样方式,我们可以通过一个例子来解释。
假设有三个服务A,B,C,且存在一个简单的调用方式:A->B->C, 当服务A收到请求时,Jaeger检查该请求有没有trace信息,如果没有,将为其生成新的trace(TraceId为随机生成的),并基于当前的取样策略进行sampling。该取样策略会随着请求一路广播到服务B和C,因此这些服务将必须再做采样的策略选择。这种采样方式确保了当一个trace被采用后,它的所有后续spans都会被存储起来(若每层服务都再做一次采样策略选择的话,我们就会很难获取到完整的一个trace了)。
4. 代码入侵性
关于装载的方法,不同语言在网上的代码示例都很多。对于tracing这种监控类系统,一定不能对我们的业务代码侵入太高,因为我们的项目代码为golang,下面以golang代码中grpc下,jaeger的代码侵入性比较(为了提高可读性,直接展示出diff信息):
我们看到,利用grpc的interceptor功能,jager只需要在拦截器中插入一个interceptor即可,整体代码的影响之有5行左右。(注:在业务代码中,grpc使用context来携带信息)
5. Jaeger使用
当我们正是使用jager后,可以通过两种方式来进行查看:
根据TraceId搜索
通过Web UI左上方,可以直接键入TraceId进行某次trace的搜索
根据服务节点查看
通过Web UI左边栏Find Traces,可以详细地进行高级搜索功能,支持服务名,操作,Tag信息(Jaeger中的tag功能,可以在context中加入tag,进行更过的标识)等。当我们确定搜索条件后,就可以查出符合条件的trace信息了