链路追踪系统最早是由Goggle公开发布的一篇论文
《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》
链路追踪系统原理
traceId串联请求形成链路:chrome -> 服务A -> 服务B -> 服务C -> 服务D -> 服务E -> 服务C -> 服务A -> chrome。服务间经过的局部链路构成了一条完整的链路,其中每一条局部链路都用一个全局唯一的traceid来标识。
Spanid从小到大表示请求的顺序,spanid和parentid构成了父子关系。通过事先在日志中埋点,找出相同traceId的日志,再加上parent id和span id就可以将一条完整的请求调用链串联起来。
几大开源组件的地址:
推特 zipkin -> https://zipkin.io/ github -> https://github.com/openzipkin/zipkin/
Uber Jaeger -> https://www.jaegertracing.io/
Uber Pinpoint -> https://github.com/pinpoint-apm/pinpoint
Apache SkyWalking -> http://skywalking.apache.org/
Zipkin
Zipkin早于Jaeger,是Google Dapper的开源版本,由Twitter进一步开发。Zipkin基于Java语言的应用程序,其中包含很多服务,每个服务都实现Zipkin具体的某一个功能,并包括一个用户界面和用于跟踪软件系统框架的界面。每个服务还提供了一系列存储引擎来持久存储数据,例如内存数据库,MySQL,Cassandra和Elasticsearch。
此外,Zipkin还提供了传输机制(如RabbitMQ,Scribe,HTTP和Kafka)以及用于在Cassandra中存储数据的基于节点的服务器。Zipkin支持大多数流行的高级语言,包括C#,Java和JavaScript。
Jaeger
由Uber创建,并用Go语言编写。它除了Zipkin的功能集外,Jaeger还提供了动态采样,REST API,基于ReactJS的UI界面,以及对Cassandra和Elasticsearch内存数据存储的支持。为了实现这些功能,Jaeger相比Zipkin采取了一种不同的,更分散的方法。
Jaeger的体系结构包括一个客户端,该客户端向代理发出跟踪,代理监听入站跨度(spans)并将其路由到收集器。然后,收集器将验证,转换并保留跨度(spans)。
Jaeger的分布式体系结构使其具有高度可扩展性。Jaeger还具有独特的数据收集方式:与其他尝试收集轨迹和跨度(spans)的系统不同,Jaeger会对监视的数据进行动态采样。这种方法不仅可以处理突然的流量激增,而且可以提高Jaeger的整体性能。
Zipkin和Jaeger的优势:
Zipkin成熟
Zipkin是更成熟的平台。它拥有广泛的行业支持,拥有庞大而活跃的社区。Zipkin用Java编写,非常适合企业环境。但是,它也支持大多数流行的高级语言,如果你不知道或不喜欢Java,那么这很好。无论你选择哪种语言,Zipkin都支持OpenTracing,OpenCensus和OpenTelemetry(这三大开放跟踪框架),并具有广泛的可扩展性选项和工具集成。
Jaeger性能高
Jaeger与Zipkin大致相似,但具有一些独特的功能。首先,它具有更现代的设计和体系结构。其分布更广泛的方法具有高度的灵活性和高性能。Jaeger为你提供了一个基于Web的UI,你可以轻松地对其进行部署和扩展。
Zipkin和Jaeger的劣势:
Zipkin灵活性低
由于Zipkin是两者中的较老者,因此其较旧的设计使用的模块化程度较低,与新的竞争对手相比,它速度更慢且灵活性更低。尽管对于较小的系统,这种差异可能无关紧要,但是随着系统开始增长或需要快速扩展,这可能会成为问题。Zipkin的模块化程度较低的设计缺乏新方法的灵活性,可能会影响其整体性能。
Zipkin的核心组件是用Java编写的,这对于任何重视稳定性而不是性能的组织都非常有用。Zipkin提供了支持许多开发语言,但没有对一些流行语言(如Python,Ruby和PHP)进行支持。
Jaeger复杂且难以维护
Jaeger可能会更新,但这并不一定意味着它会更好。实际上,许多人(尤其是企业IT部门的人)会将Jaeger的相对不成熟视为劣势。Jaeger选择Go作为主要语言,Go是作为一种系统语言编写的,但是它远没有Java流行。这意味着你可能必须学习一种新的语言,而不是去学习一种已知的语言。
Jaeger的另一个既是福也是祸的领域是其更现代的设计。这种体系结构在性能,可靠性和可伸缩性方面提供了很多好处,但是它也更加复杂且难以维护。
Zipkin和Jaeger的抉择:
Zipkin和Jaeger具有广泛的扩展性选项和工具集成,并且都支持虚拟化和容器化。两种工具都依赖于内存存储,并且面临类似的数据丢失问题。
对于那些重视稳定性的组织,Zipkin是更好的选择。它更加成熟,拥有越来越大的社区。Zipkin具有广泛的行业支持,其基于Java开发使其适用于目前的IT世界。
Jaeger虽然缺乏成熟度,但它具有速度快和灵活性高的特点,还有更高的性能,并且更易于扩展。
Zipkin Slim
Zipkin Slim构造更小,启动速度更快。它支持内存和Elasticsearch存储,但不支持Kafka或RabbitMQ等消息传递传输。
Zipkin的整体架构图
• Instrumented client和Instrumented server需要集成在分布式系统的具体服务中,采集跟踪信息,调用Transport,把跟踪信息发送给Zipkin的Server。
• Transport是Zipkin对外提供的接口,支持HTTP、Kafka、Scribe等通信方式。
• Zipkin即Zipkin server,主要包括四个模块:
Collector: 用于接收各个应用服务传输的追踪信息;
Storage:Zipkin的后端存储,支持In-Memory、MySql、Elasticsearch和Cassandra;
API:提供对外的查询接口;
UI:提供对外的Web界面。
Http Tracing的时序图
用户的请求/foo首先被Trace Instrumentationlan拦截,记录下Tags,时间戳,同时在Header里增加Trace信息,然后再流转到后端服务进行处理,处理完成后,正常响应,Trace Instrumentationlan拦截响应,记录处理延时后,将Response正常返回给调用方,同时异步地将Trace的Span发送给Zipkin Server。Span中的traceId是在整个调用链路上唯一的ID,用于唯一标识一条调用链。