week6 LiTianyi - XLab-Tongji/AIOpsConceptualModeling GitHub Wiki
JAEGER LEARNING
Jaeger是一个分布式tracing system,用来监测和诊断基于微服务的分布式系统,包括:
-
分布式上下文传播
-
分布式交易监控
-
根本原因分析
-
服务依赖性分析
-
性能/延迟优化
特点
- OpenTracing兼容的数据模型和工具库
- Go,Java,Node,Python, C ++和C#
- 对每个服务/端点概率使用一致的前期采样
- 多个存储后端:Cassandra,Elasticsearch,内存。
- 系统拓扑图
- 自适应采样(即将推出)
- 收集后数据处理管道(即将推出)
高扩展性
Jaeger后端的设计没有单点故障,可以根据业务需求进行扩展。例如,Uber上任何给定的Jaeger安装通常每天要处理数十亿个跨度。
对OpenTracing的本机支持
Jaeger后端,Web UI和工具库是从头开始设计的,以支持OpenTracing标准。
- 通过span references奖traces表示为有向无环图(不仅是树)
- 支持强类型的span tags和structured logs
- 通过baggage支持通用的分布式上下文传播机制
云原生部署
Jaeger后端作为Docker映像的集合进行分发。二进制文件支持各种配置方法,包括命令行选项,环境变量和多种格式(yaml,toml等)的配置文件。Kubernetes运营商,Kubernetes模板 和Helm图表协助部署到Kubernetes集群。
可观察性
所有Jaeger后端组件默认情况下都公开Prometheus metrics(也支持其他指标后端)。使用结构化日志库zap将日志写到标准输出。
拓扑图
Jaeger UI支持两种类型的服务图:System Architecture和Deep Dependency Graph。
系统结构
架构中观察到的所有服务的“经典”服务依赖关系图。该图仅表示服务之间的单跳相关性,类似于从服务网格产生的遥测中可以获得的相关性。例如,一个图A - B - C
,有一些含有A
和B
之间的call,和一些B
和C
之间的call。但是,这并不意味着有任何trace包含完整的链A - B - C
,即我们不能说A
依赖于C
。
此图的节点粒度仅是服务,而不是服务端点。
可以从内存中的存储中动态构建系统架构图,或者在使用分布式存储时使用Spark或Flink作业来构建。
深度依赖图
也称为“传递依赖图”,其中链A -> B -> C
表示对A
具有传递依赖C
。单个图形需要“焦点”服务(以粉红色显示),并且仅显示通过该服务的路径。通常,这种类型的图并不代表系统的完整体系结构,除非存在连接到所有内容的服务(例如API网关),并且将其选择为焦点服务。
可以在服务和服务端点之间更改此图的节点粒度。在后一种模式下,同一服务中的不同端点将显示为单独的节点,例如A::op1
和A::op2
。
此时,只能根据搜索结果中的迹线构造可传递图。将来将有一个Flink作业,它将通过汇总所有迹线来计算图形。
结构
Jaeger客户端库
Jaeger客户端是OpenTracing API特定于语言的实现。它们可用于手动或与已经与OpenTracing集成的各种现有开源框架(例如Flask,Dropwizard,gRPC等)一起为分布式跟踪应用程序进行检测。
检测服务在接收新请求时创建spans,并将上下文信息(trace ID,span ID和baggage)附加到传出请求。只有id和baggage随请求一起传播;所有其他概要分析数据(如操作名称,时间,标签和日志)都不会传播。相反,它在后台异步地传输到Jaeger后端。
工具设计为始终在生产中使用。为了最大程度地减少开销,Jaeger客户采用了各种采样策略。采样跟踪时,将捕获分析范围数据并将其传输到Jaeger后端。当不对跟踪进行采样时,根本不会收集任何性能分析数据,并且对OpenTracing API的调用会被短路,以产生最小的开销。默认情况下,Jaeger客户端对0.1%的迹线进行采样(每1000条中的1条),并且能够从Jaeger后端检索采样策略。
Agent
JaegerAgent是一个网络守护程序,它侦听通过UDP发送的span,然后将其分批发送给collector。它旨在作为基础结构组件部署到所有主机。Agent将collector的路由和发现抽象为远离客户端。
Collector
Jaeger Collector从Jaeger Agent接收traces,并通过处理管道运行它们。当前,我们的管道会验证跟踪,为其建立索引,执行任何转换并最终存储它们。
Jaeger的存储是一个可插拔组件,目前支持Cassandra,Elasticsearch和Kafka。
Query
Query是一项从存储中检索跟踪并用UI来显示trace的服务。
Ingester
Ingester是一项从Kafka主题读取并写入另一个存储后端(Cassandra,Elasticsearch)的服务。
APIs
Jaeger组件实现了各种用于保存或检索跟踪数据的API。
以下标签用于描述API兼容性保证。
- stable-API保证向后兼容。如果将来要进行重大更改,它们将导致新的API版本,例如
/api/v2
URL前缀或IDL中的其他名称空间。 - internal-用于Jaeger组件之间内部通信的API,不建议由外部组件使用。
- deprecated-仅出于遗留原因进行维护的API,将来会逐步淘汰。
Span reporting APIs
agent和collector是Jaeger后端的两个组件,可以接收span。目前,它们支持两组非重叠的API。
Thrift over UDP (stable)
Agent只能接收Thrift格式的UDP span。主要API是UDP数据包,其中包含jaeger-idl存储库Batch
中jaeger.thrift IDL文件中定义的Thrift编码结构。大多数Jaeger客户端使用Thrift的compact
编码,但是某些客户端库不支持它(特别是Node.js),而使用Thrift的binary
编码(发送到不同的UDP端口)。Agent的API由agent.thrift IDL文件定义。
由于遗留原因,该代理还接受Zipkin格式的跨度,但是,只有非常旧版本的Jaeger客户端才能发送该格式的数据,并且已正式弃用该数据。
Protobuf via gRPC (stable)
在典型的Jaeger部署中,代理会从客户端接收跨度并将其转发给收集器。从Jaeger 1.11版开始,代理和收集器之间的官方推荐协议是gRPC与Protobuf,如collector.proto IDL文件中所定义。
Thrift over HTTP (stable)
在某些情况下,将Jaeger Agent部署在应用程序旁边是不可行的,例如,当应用程序代码作为AWS Lambda函数运行时。在这些情况下,可以将Jaeger Clients配置为通过HTTP / HTTPS将span直接提交给collector。
可以在HTTP POST请求中将相同的jaeger.thrift有效负载提交给/api/traces
端点,例如https://jaeger-collector:14268/api/traces
。Batch
需要使用Thrift的binary
编码对结构进行编码,并且HTTP请求应指定内容类型标头:
Content-Type: application/vnd.apache.thrift.binary
JSON over HTTP (n/a)
Collector没有官方的Jaeger JSON格式。将来可能会支持Protobuf生成的JSON。
Zipkin Formats (stable)
Jaeger Collector也可以接受几种Zipkin数据格式的span,即JSON v1 / v2和Thrift。需要将收集器配置为启用Zipkin HTTP服务器,例如在Zipkin collector使用的端口9411上。服务器启用了两个期望POST请求的端点:
/api/v1/spans
用于以Zipkin JSON v1或Zipkin Thrift格式提交span。/api/v2/spans
在Zipkin JSON v2中提交span。
Trace retrieval APIs
可以通过调用Jaeger Query Service检索存储在存储器中的trace。
gRPC/Protobuf (stable)
推荐的编程方式检索跟踪和其他数据的方法是通过query.protoI DL文件中定义的gRPC端点。
HTTP JSON (internal)
Jaeger UI通过JSON API与Jaeger Query Service通信。例如,可以通过GET请求来检索tracehttps://jaeger-query:16686/api/traces/{trace-id-hex-string}
。此JSON API故意未记录在案,并且可能会发生变化。
Clients configuration (internal)
客户端库不仅将完成的span提交到Jaeger后端,而且还定期轮询Agents以获取各种配置,例如采样策略。有效载荷的模式被定义sampling.thrift,用节俭的内置JSON生成功能编码为JSON。
Service dependencies graph (internal)
可以从/api/dependencies
端点的Query Service检索。GET请求需要两个参数:
endTs
(自epoch以来的毫秒数)-时间间隔的结束lookback
(以毫秒为单位)-时间间隔的长度(即开始时间+回溯=结束时间)。
返回的JSON是表示为元组的edges的list(caller, callee, count)
。
通过编程方式访问服务图,推荐的API是上述的gRPC / Protobuf。