运维那些事之调用链工具Jaeger
Jaeger简介
Jaeger 是Uber推出的一款开源分布式追踪系统,兼容OpenTracing API。UI相较于Zipkin的更加直观和丰富,还有一个则是sdk比较丰富,go语言编写,上传采用的是udp传输,效率高速度快。相比
jaeger的开发语言是`golang`
jaeger支持OpenTracing协议,同属于CNCF基金会
jaeger支持各种各样的客户端,包括Go、Java、Node、Python、C++等
jaeger支持udp协议传输,当然也支持http
Jaeger架构
从以上架构图可以看出,jaeger将jaeger-agent从业务应用中抽出,部署在宿主机或容器中,专门负责向collector异步上报调用链跟踪数据,这样做将业务应用与collector解耦了,同时也减少了业务应用的第三方依赖。另外jaeger整体是用go语言编写的,在并发性能、对系统资源的消耗上也对基于java的openzipkin好不少。
其中jaeger-collector和jaeger-query是必须的,其余的都是可选的,我们没有采用agent上报的方式,而是让客户端直接通过endpoint上报到collector。
1. Jaeger-client
是Jaeger客户端代码库,便于不同语言的项目来介入到Jaeger中,当我们的应用程序装载上之后,client会负责收集并发送数据到Agent。
· 实现了OpenTracing API接口
· 当应用建立Span并发出请求到下游的服务时,它会附带跟踪信息(Trace ID, Span ID, baggage)。其他信息比如请求的名字,请求的参数,日志不会发给下游服务,而会被取样并异步的通过Jaeger-client发送到Jaeger-agent。
· 因为创建跟踪信息的代价很小,跟踪功能是默认开启的。
· 虽然跟踪功能是默认开启,但只有一部分的跟踪会被记录下来。默认比例是0.1%的取样
下图为具体实现原理:
2. Jaeger-agent:
是Jaeger客户端代理,jaeger的agent,是一个监听在 UDP 端口上接收 span 数据的网络守护进程。 如同大多数分布式系统都拥有一个Agent一样,Jaeger的Agent有以下几类特点:
· agent收集并汇聚这些span信息到collector;
· agent的被设计成一个基础组件,旨在作为基础架构组件部署到所有宿主机;
· agent将client library 和 collector 解耦,为 client library 屏蔽了路由和发现 collector 的细节;
总结如下:
· 与应用运行在同一个机器里
· 负责接受从客户端通过UDP发来的Trace/Span信息
· 批量上传到Jaeger收集器
3. Jaeger-collector
collector,顾名思义,从agent收集traces信息,并通过处理管道处理他们,再写入后端存储(backends)。
当前的collector工作主要是管理trace,建立索引,执行相关转换,并最终存储它们。
Collector中运行着sampling逻辑,根据我们设定的sampling方式对数据进行收集和处理。
总结如下:
· 接受从agent发来的Trace/Span信息
· 进行信息校验,索引和存储到后台的数据库
4. DB
即数据存储。Jaeger的存储是一个可插拔的组件,目前支持Cassandra,Elasticsearch和Kafka(当然也支持纯内存方式,但是不适用于生产环境),我们生产环境使用的ES。
5. Query & UI
数据查询与前端界面展示。Query查询是一种从存储中检索trace,并提供UI以显示它们的服务。Jaeger 原生UI可以展示了一次Trace的数据流向,作为一次系统作用的数据传播/执行图。生产环境可以与Kibana配合使用,增加其统计能力。
Jaeger部署
环境信息
注: jaeger支持ES和Canssandra两种后端DB。由于之前已经部署过ES集群 本例就使用ES存储。
下载安装包
包括:
jaeger-agent
jaeger-collector
jaeger-query
jaeger-standalone
jaeger-ingester
example-hotrod 模拟APP 模拟Uber打车过程
增加执行权限 chmod a+x jaeger-*
由于启动命令参数较多,先创建几个执行脚本 来启动jaeger
start-collector.sh
export SPAN_STORAGE_TYPE=elasticsearch
nohup ./jaeger-collector --es.server-urls http://100.120.249.239:9200/ --log-level=debug > collector.log 2>&1 &
start-agent.sh
export SPAN_STORAGE_TYPE=elasticsearch
nohup ./jaeger-agent --collector.host-port=100.120.249.239:14267 --discovery.min-peers=1 --log-level=debug > agent.log 2>&1 &
start-query.sh
export SPAN_STORAGE_TYPE=elasticsearch
nohup ./jaeger-query --span-storage.type=elasticsearch --es.server-urls=http://100.120.249.239:9200/ > query.log 2>&1 &
测试例子部署运行:
./example-hotrod frontend -p 8084
./example-hotrod customer
./example-hotrod driver
./example-hotrod route
UI
例子测试前端
具体流程
frontend 服务接收 /dispatch 进行请求分发
frontend 调用服务 custom(/customer),custom 服务通过 mysql 获取消费者信息
frontend 调用服务 driver,rpc 调用( findNearest)从 redis 找到距离消费者最近的 10 个车辆
frontend 并行调用服务 route,route 服务 /route 计算各个车辆到消费者的路径。这里并行可以通过打开信息流图可以发现每次 3 个一组,据此可以估计线程池大小为 3。
配置
1、 Jaeger-Client配置
源码路径:jaeger-client-go/config.go
type Configuration struct {
// ServiceName specifies the service name to use on the tracer.
// Can be provided via environment variable named JAEGER_SERVICE_NAME
ServiceName string `yaml:"serviceName"`
// Disabled can be provided via environment variable named JAEGER_DISABLED
Disabled bool `yaml:"disabled"`
// RPCMetrics can be provided via environment variable named JAEGER_RPC_METRICS
RPCMetrics bool `yaml:"rpc_metrics"`
// Tags can be provided via environment variable named JAEGER_TAGS
Tags []opentracing.Tag `yaml:"tags"`
Sampler *SamplerConfig `yaml:"sampler"`
Reporter *ReporterConfig `yaml:"reporter"`
Headers *jaeger.HeadersConfig `yaml:"headers"`
BaggageRestrictions *BaggageRestrictionsConfig `yaml:"baggage_restrictions"`
Throttler *ThrottlerConfig `yaml:"throttler"`
}
实例:
disabled: false //是否不启动span上报能力
sampler: // 采样配置
type: const
param: 1.0
samplingServerURL:
maxOperations:
samplingRefreshInterval:
reporter: //上报配置
queueSize:
logSpans:
localAgentHostPort: 100.120.249.239:6831
collectorEndpoint: //jaeger支持直接上报Span到Collector不经过Agent
user:
password:
采样配置type 当前支持4种采样设置:
· 固定采样(sampler.type=const)sampler.param=1 全采样, sampler.param=0 不采样;
· 按百分比采样(sampler.type=probabilistic)sampler.param=0.1 则随机采十分之一的样本;
· 采样速度限制(sampler.type=ratelimiting)sampler.param=2.0 每秒采样两个traces;
· 动态获取采样率 (sampler.type=remote) 这个是默认配置,可以通过配置从 Agent 中获取采样率的动态设置。