Jaeger [ˈdʒɛgər] 是Uber公司开发的一套分布式追踪系统,受启发于 dapper 和 OpenZipkin,兼容 OpenTracing 标准,CNCF的开源项目。
由于 Uber 的业务增长迅猛,其软件架构也越来越复杂,截止 2015 年下半年,Uber 内部已经有 500 多个微服务在运行,给问题排查和性能分析带来巨大困难。2016 年 4 月,Uber 启动 Jaeger 项目,并逐渐在内部推行分布式追踪系统,一年之后(2017 年 4 月),Uber 宣布正式将 Jaeger 开源。Uber Engineering Blog 有一篇文章介绍了分布式追踪系统在 Uber 的演进过程:《Evolving Distributed Tracing at Uber Engineering》。
题外话,2017 年的 QCon 上,滴滴也分享了分布式追踪系统的实践,题为《异构系统链路追踪——滴滴 trace 实践》,可以搜索演讲视频学习一下。
图片来源:Jaeger Architecture
Jaeger 的架构非常清晰,部署起来也很轻松,Docker Hub 中有官方打好的 Image,可以拿来直接用,https://hub.docker.com/u/jaegertracing/。如果是本地测试,可以直接用 Jaeger 的 all-in-one Image,
下载地址:https://www.jaegertracing.io/download/
下载后并解压:
进入到解压后的目录执行:
./jaeger-all-in-one
目测启动后,访问地址:http://{{IP}}:16686/
集成了整套环境,利用内存存储:docker hub地址:https://hub.docker.com/r/jaegertracing/all-in-one。
执行一下命令,可以在本机拉起一个 jaeger 环境,上报的链路数据保存在本地内存,所以只能用于测试。
$ docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \kaixiao
-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://{{IP}}:16686/可以在浏览器查看 Jaeger UI
Agent:
它们之间的传输协议都是基于thrift封装的。
Collector:
Query:
UI:
Jaeger 官方提供了一个 Demo Application,可以用作代码参考,链接为 Hot R.O.D. - Rides on Demand。
假设你的微服务系统已经有了中心化的日志收集和处理系统,如果还没有的话,强烈建议部署一套 ELK(或者EFK)。
再假设对于每一个请求,都会有一个贯穿整个请求始末的 Request ID,如果还没有的话,强烈建议加一个。
以上准备完毕后,可以选取一个分布式追踪系统,集成到服务当中,建议采用 Jaeger。
重点来了,在 Trace 的起始处,将 Trace ID 设置为 Request ID,这么一来就打通了日志系统和分布式追踪系统,可以使用同一个 ID 查询请求的事件流和日志流,从此开启了上帝视角。
支持设置采样率是 Jaeger 的一个亮点,在生产环境中,如果对每个请求都开启 Trace,必然会对系统性能带来一定压力,除此之外,数量庞大的 Span 也会占用大量的存储空间。
为了尽量消除分布式追踪采样对系统带来的影响,应该基于不同的场景设置不同的采样策略。
Jaeger 支持四种采样策略,分别是 const
、probabilistic
、rateLimiting
和 remote
。
const
全量采集,采样率的可设置的值为 0 和 1,分别表示关闭采样和全部采样。probabilistic
概率采集,默认万份之一,取值可在 0 至 1 之间,如0.5 表示只对 50% 的请求采样。rateLimiting
限速采集,则是设置每秒的采样次数上限。remote
按远程设置的一种动态采集策略,取值的含义和 probabilistic
相同,都意为采样的概率,只不过设置为 remote
后,Client 会从 Jaeger Agent 中动态获取采样率设置。remote是采样器的默认值,当我们不做配置时,会从 Jaeger 后端中央配置甚至动态地控制服务中的采样策略。
详细说明:https://www.jaegertracing.io/docs/1.22/sampling/
Jaeger 是分布式链路追踪工具,如果不用在跨进程上,那么 Jaeger 就失去了意义。而微服务中跨进程调用,一般有 HTTP 和 gRPC 两种,接下来以Go代码为例,从浅入深和大家一起学习如何在实际场景中使用Jaeger。
主要会用到两个依赖:
开始练习: opentracing-jaeger在Go平台下的使用教程
References: