1、skywalking源码--Agent收集trace数据

本文深入剖析SkyWalking 8.9.0版本中的链路追踪机制,详细介绍了trace数据的创建、暂存及传递过程涉及的主要类和方法。特别关注了trace和context相关的类,如TraceSegment、AbstractTracingSpan等。

本源码来自于skywalking-agent 8.9.0版本

注:本篇文章主要是作为自己看书后的总结,内容有可能会存在一些个人理解上的偏差,如果有网友找出问题欢迎提出,感谢!!!如果我理解上的错误误导了您,在此表示抱歉!!!

概述

本篇文章讲述trace数据的创建、暂存、传递过程所涉及的类、方法实现,相关代码在apm-agent-core模块,主要是context包下的类。本篇主要讲述 trace和context 相关类。我们在下一篇还会根据本篇来讲述我们公司在这块的改造,敬请期待!!!

代码截图

在这里插入图片描述

trace

一个完整的trace可以简单的描述为segment、spand、id组成,当然实际并不是这样的,它更加复杂,因为这里里面涉及到跨进程、跨线程的传递、如何高效发送,所以会产生一些其他的存储对象。因此我们可以理解为在每个进程内都会存储一个 segment,这个segment里面会去处理跨进程、跨线程的传递、如何高效发送这些问题。

Segment相关

这个就是上面讲的segment。

代码
public class TraceSegment {
   
   
    /**
     * The id of this trace segment. Every segment has its unique-global-id.
     */
    private String traceSegmentId;

    /**
     * The refs of parent trace segments, except the primary one. For most RPC call, {@link #ref} contains only one
     * element, but if this segment is a start span of batch process, the segment faces multi parents, at this moment,
     * we only cache the first parent segment reference.
     * <p>
     * This field will not be serialized. Keeping this field is only for quick accessing.
     */
    private TraceSegmentRef ref;

    /**
     * The spans belong to this trace segment. They all have finished. All active spans are hold and controlled by
     * "skywalking-api" module.
     */
    private List<AbstractTracingSpan> spans;

    /**
     * The <code>relatedGlobalTraceId</code> represent the related trace. Most time it related only one
     * element, because only one parent {@link TraceSegment} exists, but, in batch scenario, the num becomes greater
     * than 1, also meaning multi-parents {@link TraceSegment}. But we only related the first parent TraceSegment.
     */
    private DistributedTraceId relatedGlobalTraceId;

    private boolean ignore = false;

    private boolean isSizeLimited = false;

    private final long createTime;

    /**
     * Create a default/empty trace segment, with current time as start time, and generate a new segment id.
     */
    public TraceSegment() {
   
   
        this.traceSegmentId = GlobalIdGenerator.generate();
        this.spans = new LinkedList<>();
        this.relatedGlobalTraceId = new NewDistributedTraceId();
        this.createTime = System.currentTimeMillis();
    }

    public TraceSegment(boolean ignore) {
   
   
        this();
        this.ignore = ignore;
    }

    /**
     * Establish the link between this segment and its parents.
     *
     * @param refSegment {@link TraceSegmentRef}
     */
    public void ref(TraceSegmentRef refSegment) {
   
   
        if (null == ref) {
   
   
            this.ref = refSegment;
        }
    }

    /**
     * Establish the line between this segment and the relative global trace id.
     */
    public void relatedGlobalTrace(DistributedTraceId distributedTraceId) {
   
   
        if (relatedGlobalTraceId instanceof NewDistributedTraceId) {
   
   
            this.relatedGlobalTraceId = distributedTraceId;
        }
    }

    /**
     * After {@link AbstractSpan} is finished, as be controller by "skywalking-api" module, notify the {@link
     * TraceSegment} to archive it.
     */
    public void archive(AbstractTracingSpan finishedSpan) {
   
   
        spans.add(finishedSpan);
    }

    /**
     * Finish this {@link TraceSegment}. <p> return this, for chaining
     */
    public TraceSegment finish(boolean isSizeLimited) {
   
   
        this.isSizeLimited = isSizeLimited;
        return this;
    }

    public String getTraceSegmentId() {
   
   
        return traceSegmentId;
    }

    /**
     * Get the first parent segment reference.
     */
    public TraceSegmentRef getRef() {
   
   
        return ref;
    }

    public DistributedTraceId getRelatedGlobalTrace() {
   
   
        return relatedGlobalTraceId;
    }

    public boolean isSingleSpanSegment() {
   
   
        return this.spans != null && this.spans.size() == 1;
    }

    public boolean isIgnore() {
   
   
        return ignore;
    }

    public void setIgnore(boolean ignore) {
   
   
        this.ignore = ignore;
    }

    /**
     * This is a high CPU cost method, only called when sending to collector or test cases.
     *
     * @return the segment as GRPC service parameter
     */
    public SegmentObject transform() {
   
   
        SegmentObject.Builder traceSegmentBuilder = SegmentObject.newBuilder();
        traceSegmentBuilder.setTraceId(getRelatedGlobalTrace().getId());
        /*
         * Trace Segment
         */
        traceSegmentBuilder.setTraceSegmentId(this.traceSegmentId);
        // Don't serialize TraceSegmentReference

        // SpanObject
        for (AbstractTracingSpan span : this.spans) {
   
   
            traceSegmentBuilder.addSpans(span.transform());
        }
        traceSegmentBuilder.setService(Config.Agent.SERVICE_NAME);
        traceSegmentBuilder.setServiceInstance(Config.Agent.INSTANCE_NAME);
        traceSegmentBuilder.setIsSizeLimited(this.isSizeLimited);

        return traceSegmentBuilder.build();
    }

    @Override
    public String toString() {
   
   
        return "TraceSegment{" + "traceSegmentId='" + traceSegmentId + '\'' + ", ref=" + ref + ", spans=" + spans + "}";
    }

    public long createTime() {
   
   
        return this.createTime;
    }
}
属性|方法讲解

traceSegmentId:这个就是segment的id,代表具体某个请求在这个进程内的编号,它和traceId的生成规则一样(实例编号+线程编号+时间戳)也是全局唯一的,由GlobalIdGenerator.generate()生成。

ref:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值