在微服务为咱们提供了模块分,低耦合的高效开发和DevOPS中,具体业务中当一个请求中,请求了多个服务单元,若是请求出现了错误或异常,很难去定位是哪一个服务出了问题,这时就须要链路追踪。可能你会想在业务系统中请求中埋点,或写日志,可是这种都须要在业务代码中来写,并且耦合在代码中,不具有微服务的扩张性后后期的易维护行。python
受Dapper和OpenZipkin启发的Jaeger是由Uber Technologies做为开源发布的分布式跟踪系统。它用于监视和诊断基于微服务的分布式系统,包括:git
Jaeger后端的设计没有单点故障,能够根据业务需求进行扩展。例如,Uber上任何给定的Jaeger安装一般天天要处理数十亿个跨度。github
Jaeger后端,Web UI和工具库已彻底设计为支持OpenTracing标准。docker
经过跨度引用将迹线表示为有向无环图(不只是树)shell
支持强类型的跨度标签和结构化日志经过行李数据库
支持通用的分布式上下文传播机制json
Jaeger支持两个流行的开源NoSQL数据库做为跟踪存储后端:Cassandra 3.4+和Elasticsearch 5.x / 6.x / 7.x。正在进行使用其余数据库的社区实验,例如ScyllaDB,InfluxDB,Amazon DynamoDB。Jaeger还附带了一个简单的内存存储区,用于测试设置。后端
Jaeger Web UI是使用流行的开源框架(如React)以Javascript实现的。v1.0中发布了几项性能改进,以容许UI有效处理大量数据,并显示具备成千上万个跨度的跟踪(例如,咱们尝试了具备80,000个跨度的跟踪)。api
Jaeger后端做为Docker映像的集合进行分发。这些二进制文件支持各类配置方法,包括命令行选项,环境变量和多种格式(yaml,toml等)的配置文件。Kubernetes模板和Helm图表有助于将其部署到Kubernetes集群。安全
默认状况下,全部Jaeger后端组件都公开Prometheus指标(也支持其余指标后端)。使用结构化日志库zap将日志写到标准输出。
Jaeger的第三方安全审核可在https://github.com/jaegertracing/security-audits中得到。有关Jaeger中可用安全机制的摘要,请参见问题#1718。
尽管咱们建议使用OpenTracing API来对应用程序进行检测并绑定到Jaeger客户端库,以从其余地方没法得到的高级功能中受益,可是若是您的组织已经使用Zipkin库对检测进行了投资,则没必要重写全部代码。Jaeger经过在HTTP上接受Zipkin格式(Thrift或JSON v1 / v2)的跨度来提供与Zipkin的向后兼容性。从Zipkin后端切换只是将流量从Zipkin库路由到Jaeger后端的问题。
您的应用程序必须通过检测,而后才能将跟踪数据发送到Jaeger后端。查看“客户端库”部分,以获取有关如何使用OpenTracing API以及如何初始化和配置Jaeger跟踪器的信息。
您的应用程序必须通过检测,而后才能将跟踪数据发送到Jaeger后端。查看“客户端库”部分,以获取有关如何使用OpenTracing API以及如何初始化和配置Jaeger跟踪器的信息。
多合一是用于快速本地测试的可执行文件,具备内存存储组件,可启动Jaeger UI,收集器,查询和代理。开始多合一的最简单方法是使用发布到DockerHub的预构建映像(单个命令行)。
docker run -d --name jaeger \
-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:1.14
复制代码
Or run the jaeger-all-in-one(.exe)
executable from the binary distribution archives:
jaeger-all-in-one --collector.zipkin.http-port=9411
复制代码
You can then navigate to http://localhost:16686
to access the Jaeger UI.
容器须要暴露的端口
Port | Protocol | Component | Function |
---|---|---|---|
5775 | UDP | agent | accept zipkin.thrift over compact thrift protocol (deprecated, used by legacy clients only) |
6831 | UDP | agent | accept jaeger.thrift over compact thrift protocol |
6832 | UDP | agent | accept jaeger.thrift over binary thrift protocol |
5778 | HTTP | agent | serve configs |
16686 | HTTP | query | serve frontend |
14268 | HTTP | collector | accept jaeger.thrift directly from clients |
14250 | HTTP | collector | accept model.proto |
9411 | HTTP | collector | Zipkin compatible endpoint (optional) |
HotROD(按需乘车)是一个演示应用程序,由几个微服务组成,并说明了OpenTracing API的用法。博客文章中提供了一个教程/演练:以OpenTracing API.的方式进行HotROD。它能够独立运行,但须要Jaeger后端才能查看跟踪。Take OpenTracing for a HotROD ride
mkdir -p $GOPATH/src/github.com/jaegertracing
cd $GOPATH/src/github.com/jaegertracing
git clone git@github.com:jaegertracing/jaeger.git jaeger
cd jaeger
make install
go run ./examples/hotrod/main.go all
复制代码
docker run --rm -it \
--link jaeger \
-p8080-8083:8080-8083 \
-e JAEGER_AGENT_HOST="jaeger" \
jaegertracing/example-hotrod:1.14 \
all
复制代码
Run example-hotrod(.exe)
executable from the binary distribution archives:
$ example-hotrod all
复制代码
Then navigate to http://localhost:8080
.
收集器服务公开了Zipkin兼容的REST API / api / v1 / spans,该API接受Thrift和JSON。此外,还有/ api / v2 / spans用于JSON和Proto。默认状况下,它是禁用的。可使用--collector.zipkin.http-port = 9411启用它
Zipkin Thrift IDL and Zipkin Proto IDL files can be found in jaegertracing/jaeger-idl repository. They’re compatible with openzipkin/zipkin-api Thrift and Proto.
Span表示Jaeger中的逻辑工做单元,具备操做名称,操做的开始时间和持续时间。跨度能够嵌套并排序以创建因果关系模型。
每一个 Span 包含如下对象:
跟踪是经过系统的数据/执行路径,能够看做跨度的有向无环图。
Jaeger能够做为多合一二进制(其中全部Jaeger后端组件都在单个进程中运行)进行部署,也能够做为可扩展的分布式系统进行部署,以下所述。有两个主要的部署选项:
本节详细介绍Jaeger的组成部分以及它们之间的关系。它由您的应用程序与之交互的顺序安排。
Jaeger客户端是OpenTracing API的特定于语言的实现。它们可用于手动或经过与OpenTracing集成的各类现有开源框架(例如Flask,Dropwizard,gRPC等)来检测应用程序以进行分布式跟踪。
检测服务在接收新请求时建立跨度,并将上下文信息(跟踪ID,跨度ID和行李)附加到传出请求。只有ID和行李随请求一块儿传播;不会传播构成跨度的全部其余信息,例如操做名称,日志等。取而代之的是,采样的跨度在后台异步传输到Jaeger Agents的过程外。
该仪器的开销很小,而且设计为始终在生产中启用。请注意,虽然生成了全部跟踪,但仅采样了一些。对跟踪进行采样将跟踪标记为进一步处理和存储。默认状况下,Jaeger客户端对0.1%的迹线进行采样(每1000个中的1个),而且可以从代理中检索采样策略。
Jaeger代理是一个网络守护程序,它侦听经过UDP发送的跨度,而后将其分批发送给收集器。它旨在做为基础结构组件部署到全部主机。该代理将收集器的路由和发现抽象到远离客户端的位置。
Jaeger收集器从Jaeger代理接收跟踪,并经过处理管道运行它们。当前,咱们的管道会验证跟踪,为其创建索引,执行任何转换并最终存储它们。Jaeger的存储设备是可插拔组件,目前支持Cassandra,Elasticsearch和Kafka。
查询是一项从存储中检索跟踪并托管UI来显示跟踪的服务。
Ingester is a service that reads from Kafka topic and writes to another storage backend (Cassandra, Elasticsearch).
Jaeger库实现了一致的前期(或基于头)的采样。例如,假设咱们有一个简单的调用图,其中服务A调用服务B,服务B调用服务C:A-> B->C。当服务A收到不包含跟踪信息的请求时,Jaeger跟踪器将开始新的跟踪,为其分配一个随机跟踪ID,而后根据当前安装的采样策略作出采样决定。采样决策将与请求一块儿传播到B和C,所以这些服务将不会再次作出采样决策,而是会尊重顶级服务A作出的决策。这种方法保证了,若是对跟踪进行了采样,则全部其跨度将记录在后端。若是每一个服务都作出本身的抽样决定,那么咱们不多会在后端得到完整的跟踪。
使用配置对象实例化跟踪器时,能够经过sampler.type和sampler.param属性选择采样类型。Jaeger库支持如下采样器:
sampler.type=const
) sampler always makes the same decision for all traces. It either samples all traces (sampler.param=1
) or none of them (sampler.param=0
).sampler.type=probabilistic
) sampler makes a random sampling decision with the probability of sampling equal to the value of sampler.param
property. For example, with sampler.param=0.1
approximately 1 in 10 traces will be sampled.sampler.type=ratelimiting
) sampler uses a leaky bucket rate limiter to ensure that traces are sampled with a certain constant rate. For example, when sampler.param=2.0
it will sample requests with the rate of 2 traces per second.sampler.type=remote
, which is also the default) sampler consults Jaeger agent for the appropriate sampling strategy to use in the current service. This allows controlling the sampling strategies in the services from a central configuration in Jaeger backend, or even dynamically (see Adaptive Sampling).自适应采样器是一个组合了两个功能的复合采样器:
能够静态配置每一个操做参数,也能够在远程采样器的帮助下从Jaeger后端按期提取每一个操做参数。自适应采样器旨在与Jaeger后端即将推出的自适应采样功能一块儿使用。
能够经过--sampling.strategies-file选项使用静态采样策略实例化收集器(若是使用Remote sampler配置,则将其传播到相应的服务)。此选项须要一个已定义采样策略的json文件路径。
{
"service_strategies": [
{
"service": "foo",
"type": "probabilistic",
"param": 0.8,
"operation_strategies": [
{
"operation": "op1",
"type": "probabilistic",
"param": 0.2
},
{
"operation": "op2",
"type": "probabilistic",
"param": 0.4
}
]
},
{
"service": "bar",
"type": "ratelimiting",
"param": 5
}
],
"default_strategy": {
"type": "probabilistic",
"param": 0.5
}
}
复制代码
代码示例可参考一位go大佬的一个示例:github.com/xinliangnot…