一、什么是一个Trace?
在广义上,一个trace代表了一个事务或者流程在(分布式)系统中的执行过程。在OpenTracing标准中,trace是多个span组成的一个有向无环图(DAG),每一个span代表trace中被命名并计时的连续性的执行片段。分布式追踪中的每个组件都包含自己的一个或者多个span。例如,在一个常规的RPC调用过程中,OpenTracing推荐在RPC的客户端和服务端,至少各有一个span,用于记录RPC调用的客户端和服务端信息。
按树状结构表示一个链路:
按时间顺序表示一个链路:
OpenTracing的概念学习可以参考GitHub:github.com/opentracing…
Zipkin 和 Jaeger 在多种语言环境中支持OpenTracing。
二、链路解决了什么问题
开发和工程团队因为系统组件水平扩展、开发团队小型化、服务容器化、解耦等各种需求,逐渐使用微服务架构替换老旧的单机系统。 当一个生产系统面对真正的高并发,或者解耦成大量微服务时,以前很容易实现的重点任务变得困难了。在实际应用中需要面临一系列问题:用户体验优化、后台错误原因分析,分布式系统内各组件的调用情况等。 当代分布式跟踪系统(例如,Zipkin, Dapper, HTrace, X-Trace等)旨在解决这些问题,但是他们使用不兼容的API来实现各自的应用需求。OpenTracing的出现解决了这个问题。OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。
在微服务中,正确使用链路的方式是服务间的链路+各个服务的日志,链路重点关注的是服务调用间是否出现问题,日志关注的是在本服务中出现的问题。
单条链路在服务中只需要记录server+client端的span,中间过程需要记录的地方可以打印包含traceid的日志,当微服务调用出现问题,比如错误、超时等,可以通过请求拿到traceid,先通过链路系统定位到具体服务,再根据traceid来查询在服务中的日志。链路建立索引搜索,日志保存在低成本的存储当中,当然,在服务器资源不受限的情况下,可以把服务间+服务中的调用数据全部放在trace当中。
我们可以根据服务间的链路来提取服务调用图,服务间的调用次数、错误率等等,动态监控整个微服务集群的健康情况。
三、链路系统存在的问题
大部分链路都是正常链路,存储这部分链路占用了很多资源,由于链路span发布在不同的微服务中,提前设置的采样并不能很好的满足需求。
1、当中间链路节点出现需要采样的情况时,req header向后传递采样标志,rsp header向前传递采样标志。这种在异步调用情况下,rsp header向前传递会失效。
2、采用这种标记的只能在单条链路上有效,异常节点之前出现分叉链路情况的时候,分叉的另外链路无法打上采样标记。
针对这种情况,可以使用flink对链路进行滞后的采样,收集整个trace链路之后,来完成采样:
根据traceId作为key,采用sessionTime Windows作为窗口,保证单个链路数据的span能在sessionTime内搜集到flink的source源中。
flink+trace的分析见系列文章的第三篇。