skywalking trace跟踪原理

分布式链路追踪原理详解及SkyWalking、Zipkin介绍 背景:追踪调用链路,监控链路性能,排查链路故障 随着微服务架构的流行,一次请求往往需要涉及到多个服务,需要一些可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决问题。 单体架构中可以使用 AOP 在调用具体的业务逻辑前后分别打印一下时间即可计算出整体的调用时间,使用 AOP 来 catch 住异常也可知道是哪里的调用导致的异常。 基本实现原理 一个完整请求链路的追踪ID(traceid)用于查出本次请求调用的所有服务,每一次服务调用的跨度ID(spanid. 阅读详情

 

skywalking trace跟踪原理:

1.先理解trace的几个概念,EntrySpan EntrySpan ExitSpan

https://skyapm.github.io/document-cn-translation-of-skywalking/zh/6.2.0/guides/Java-Plugin-Development-Guide.html

2.以百度的 brpc插件为例

ClientInterceptor

    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
        Request request = (Request) allArguments[0];
        InetSocketAddress remoteAddress = (InetSocketAddress) request.getChannel().remoteAddress();
        InetAddress address = remoteAddress.getAddress();
​
        final ContextCarrier contextCarrier = new ContextCarrier();
        # createExitSpan创建本地线程变量,底层是使用的 threadLocal技术
        AbstractSpan span = ContextManager.createExitSpan(generateOperationName(request), contextCarrier, address.getHostAddress() + ":" + remoteAddress.getPort());
        CarrierItem next = contextCarrier.items();
        while (next.hasNext()) {
            next = next.next();
            if (request.getKvAttachment() == null) {
                request.setKvAttachment(new HashMap<>());
            }
            # 将rpc请求放到request的请求头中,服务端获取就会从请求头中获取
            request.getKvAttachment().put(next.getHeadKey(), next.getHeadValue());
        }
        span.setComponent(ComponentsDefine.BRPC_JAVA);
        SpanLayer.asRPCFramework(span);
    }

 

    private static AbstractTracerContext getOrCreate(String operationName, boolean forceSampling) {
    #这里的get就是调用的ThreadLocal的get方法获取本线程的ThreadLcalMap对象,将来里面会放[{threadLocal1,value1},{threadLocal2,value2}],比如就可以放traceId
        AbstractTracerContext context = CONTEXT.get();
        if (context == null) {
            if (StringUtil.isEmpty(operationName)) {
                if (LOGGER.isDebugEnable()) {
                    LOGGER.debug("No operation name, ignore this trace.");
                }
                context = new IgnoredTracerContext();
            } else {
                if (EXTEND_SERVICE == null) {
                    EXTEND_SERVICE = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class);
                }
                context = EXTEND_SERVICE.createTraceContext(operationName, forceSampling);
​
            }
            CONTEXT.set(context);
        }
        return context;
    }

ServerInterceptor

public class ServerInterceptor implements InstanceMethodsAroundInterceptor {
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                             MethodInterceptResult result) throws Throwable {
        Request request = (Request) allArguments[0];
        ContextCarrier contextCarrier = new ContextCarrier();
        CarrierItem next = contextCarrier.items();
        if (request.getKvAttachment() == null) {
            request.setKvAttachment(new HashMap<>());
        }
        while (next.hasNext()) {
            next = next.next();
            #将客户端带过来的request的getHeadKey放到自己的本地线程ThreadLocalMap中(通过createEntrySpan创建)
            next.setHeadValue((String) request.getKvAttachment().get(next.getHeadKey()));
        }
​
        AbstractSpan span = ContextManager.createEntrySpan(generateOperationName(request), contextCarrier);
        SpanLayer.asRPCFramework(span);
        span.setComponent(ComponentsDefine.BRPC_JAVA);
    }
    。。。
}

3.springmvc是如何完成跟踪的?

原理是一样的

public class InvokeInterceptor implements InstanceMethodsAroundInterceptor {
    @Override
    public void beforeMethod(final EnhancedInstance objInst,
                             final Method method,
                             final Object[] allArguments,
                             final Class<?>[] argumentsTypes,
                             final MethodInterceptResult result) throws Throwable {
        ServerWebExchange exchange = (ServerWebExchange) allArguments[0];
        ContextManager.getRuntimeContext()
                      .put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, new ReactiveResponseHolder(exchange.getResponse()));
        ContextManager.getRuntimeContext()
                      .put(REQUEST_KEY_IN_RUNTIME_CONTEXT, new ReactiveRequestHolder(exchange.getRequest()));
    }

4.kafka的原理呢?

KafkaProducerInterceptor

你会发现底层还是放到head里面

public class KafkaProducerInterceptor implements InstanceMethodsAroundInterceptor {
​
    public static final String OPERATE_NAME_PREFIX = "Kafka/";
    public static final String PRODUCER_OPERATE_NAME_SUFFIX = "/Producer";
​
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                             MethodInterceptResult result) throws Throwable {
​
        ContextCarrier contextCarrier = new ContextCarrier();
​
        ProducerRecord record = (ProducerRecord) allArguments[0];
        String topicName = record.topic();
        AbstractSpan activeSpan = ContextManager.createExitSpan(OPERATE_NAME_PREFIX + topicName + PRODUCER_OPERATE_NAME_SUFFIX, contextCarrier, (String) objInst
                .getSkyWalkingDynamicField());
​
        Tags.MQ_BROKER.set(activeSpan, (String) objInst.getSkyWalkingDynamicField());
        Tags.MQ_TOPIC.set(activeSpan, topicName);
        contextCarrier.extensionInjector().injectSendingTimestamp();
        SpanLayer.asMQ(activeSpan);
        activeSpan.setComponent(ComponentsDefine.KAFKA_PRODUCER);
​
        CarrierItem next = contextCarrier.items();
        while (next.hasNext()) {
            next = next.next();
            record.headers().add(next.getHeadKey(), next.getHeadValue().getBytes(StandardCharsets.UTF_8));
        }
​
        //when use lambda expression, not to generate inner class,
        //    and not to trigger kafka CallBack class define, so allArguments[1] can't to cast EnhancedInstance
        Object shouldCallbackInstance = allArguments[1];
        if (null != shouldCallbackInstance) {
            if (shouldCallbackInstance instanceof EnhancedInstance) {
                EnhancedInstance callbackInstance = (EnhancedInstance) shouldCallbackInstance;
                ContextSnapshot snapshot = ContextManager.capture();
                if (null != snapshot) {
                    CallbackCache cache = new CallbackCache();
                    cache.setSnapshot(snapshot);
                    callbackInstance.setSkyWalkingDynamicField(cache);
                }
            } else if (shouldCallbackInstance instanceof Callback) {
                Callback callback = (Callback) shouldCallbackInstance;
                ContextSnapshot snapshot = ContextManager.capture();
                if (null != snapshot) {
                    CallbackCache cache = new CallbackCache();
                    cache.setSnapshot(snapshot);
                    cache.setCallback(callback);
                    allArguments[1] = new CallbackAdapterInterceptor(cache);
                }
            }
        }
    }

KafkaConsumerInterceptor

也是从record的header中获取的,完美搞定。

@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
                          Object ret) throws Throwable {
    /*
     * If the intercepted method throws exception, the ret will be null
     */
    if (ret == null) {
        return ret;
    }
    Map<TopicPartition, List<ConsumerRecord<?, ?>>> records = (Map<TopicPartition, List<ConsumerRecord<?, ?>>>) ret;
    //
    // The entry span will only be created when the consumer received at least one message.
    //
    if (records.size() > 0) {
        ConsumerEnhanceRequiredInfo requiredInfo = (ConsumerEnhanceRequiredInfo) objInst.getSkyWalkingDynamicField();
        KafkaContext context = (KafkaContext) ContextManager.getRuntimeContext().get(Constants.KAFKA_FLAG);
        if (context != null) {
            ContextManager.createEntrySpan(context.getOperationName(), null);
            context.setNeedStop(true);
        }
        String operationName = OPERATE_NAME_PREFIX + requiredInfo.getTopics() + CONSUMER_OPERATE_NAME + requiredInfo.getGroupId();
        AbstractSpan activeSpan = ContextManager.createEntrySpan(operationName, null).start(requiredInfo.getStartTime());
​
        activeSpan.setComponent(ComponentsDefine.KAFKA_CONSUMER);
        SpanLayer.asMQ(activeSpan);
        Tags.MQ_BROKER.set(activeSpan, requiredInfo.getBrokerServers());
        Tags.MQ_TOPIC.set(activeSpan, requiredInfo.getTopics());
​
        for (List<ConsumerRecord<?, ?>> consumerRecords : records.values()) {
            for (ConsumerRecord<?, ?> record : consumerRecords) {
                ContextCarrier contextCarrier = new ContextCarrier();
​
                CarrierItem next = contextCarrier.items();
                while (next.hasNext()) {
                    next = next.next();
                    Iterator<Header> iterator = record.headers().headers(next.getHeadKey()).iterator();
                    if (iterator.hasNext()) {
                        next.setHeadValue(new String(iterator.next().value(), StandardCharsets.UTF_8));
                    }
                }
                ContextManager.extract(contextCarrier);
            }
        }
        ContextManager.stopSpan();
    }
    return ret;
}
SkyWalking Agent数据采集和上报原理浅析 Skywalking是一款云原生的APM(应用性能管理)系统。包含了事件日志、链路追踪、指标监控能力,同时提供了数据的采集、数据存储以及数据展示三个先对独立的子系统。是一款“广义的”分布式链路追踪系统。 上一篇文章《SkyWalking如何通过修改字节码让插件生效》讲了SkyWalking的插件工作原理,这篇文章就来探索一下SkyWalking到底是如何实现链路追踪和指标监控的功能的。 整体工作原理 采集数据过程分析 链路追踪核心概念:Trace、Span。 具体在这里不展开,可以自行参考《Ope. 阅读详情

相关推荐

SkyWalking中Trace落地实现方案

Skywalking Traceid

qq_44838446的博客 3064

SkyWalking链路追踪上下文TraceContext的traceId生成的实现原理剖析

SkyWalking通过字节码增强技术实现,结合依赖注入和控制反转思想,以SkyWalking方式将追踪身份traceId编织到链路追踪上下文TraceContext中。 是不是很有趣,很有意思!!!

简放视野的专栏 9025

SpringCloudZipkin链路跟踪系统

Spring Cloud是一个非常流行的微服务框架,它提供了很多的组件可以帮助开发者快速构建分布式应用,包括配置中心、服务发现等。在实际生产环境中,由于各个服务之间的调用关系复杂,需要对服务之间的数据流进行监控,以便定位问题和优化系统性能。Spring Cloud Sleuth组件就是基于Apache Skywalking、Zipkin等开源项目实现了基于Spring Cloud的分布式链路跟踪功能。本文将会详细介绍一下Spring Cloud Zipkin链路跟踪系统。

AI天才研究院 1363

skywalking源码1---分布式追踪原理

skywalking源码,http分布式链路追踪原理

piliang719719的博客 2178

接口调试必看:status显示canceled的3种常见原因及修复方法

本文深度解析了接口调试中status显示canceled的三种核心原因:网络层中断(如请求超时)、应用层逻辑主动取消(如请求竞态、组件卸载)以及用户交互与浏览器行为。文章提供了从诊断到修复的系统性方案,包括分析Network Timing、使用Axios CancelToken、优化请求策略与性能,帮助开发者从根本上解决这一常见问题。

bb456的博客 937

众灵科技24路舵机控制器二次开发实战(1)-STM32串口指令控制详解

本文详细介绍了如何通过STM32单片机对众灵科技24路舵机控制器进行二次开发,实现串口指令控制。文章从硬件连接、通信协议解析到STM32代码实战,手把手指导开发者打通控制链路,并重点讲解了如何调用预设动作组驱动六足机器人,为后续集成传感器、无线遥控等高级功能奠定基础。

weixin_29188997的博客 484

SkyWalking 源码分析 —— Agent 收集 Trace 数据

SkyWalking Agent采用JavaAgent字节码增强技术实现分布式追踪,核心架构包含引导层、核心层、插件层和数据层。通过ByteBuddy实现插件化的字节码增强,支持静态方法、实例方法和构造器的拦截。数据模型基于Dapper论文,包含TraceSegment和Span体系,支持跨进程上下文传播。采用采样机制控制数据收集频率,通过DataCarrier实现高效缓冲和异步发送。整体设计具有无侵入、高性能、可扩展的特点,支持完整的分布式链路追踪。

油墨香^-^的博客 1037

避坑指南:QCustomPlot鼠标事件冲突解决方案(左键拖动vs右键框选)

本文深入解析QCustomPlot在QT框架下的高级交互实现,重点解决左键拖动与右键框选的冲突问题。通过自定义事件处理和QRubberBand技术,提供了一套完整的无冲突交互方案,帮助开发者优化数据可视化应用的用户体验。

moss5的博客 661

SkyWalking8.7源码解析(五):链路基本知识、链路ID生成、TraceSegment、Span基本概念、Span完整模型、StackBasedTracingSpan

21、链路基本知识 上图是一个下单接口的链路,在链路中首先要理解的概念是Segment,Segment表示一个JVM进程内的所有操作,上图中有6个Segment。Gateway Segment是Mall Segment的parent,通过parent关系就可以把多个Segment按顺序拼起来组装成一个链路 一个Segment里可能发生多个操作,如上图Segment中操作1是查Redis,操作2是查MySQL,这就是两个Span,Span表示一个具体的操作。Span之间也是基于parent的关系构建起

hxt的博客 6063

FPGA DDR3实战(四):DDR地址映射自动化测试(1)—— 测试程序设计与代码逻辑

本文介绍了一种DDR地址映射自动化测试方案,旨在提高板卡调试效率。方案通过AXI4协议实现主从端通信,构建了包含地址控制器和测试数据生成器的模块化架构。测试程序支持突发传输、状态监控和错误检测,可灵活配置测试参数。采用状态机控制流程,先写入递增数据再读取比对,完成功能验证和性能评估。该方案可系统化验证DDR的正确性、稳定性和可靠性,相比传统手动测试显著提升效率。

FPGA_小田老师的博客 1979

【OpenFOAM】-olaFlow-算例10-wavemakerTank

采用 Flap和Piston两种方式的动网格进行造波

ou_no的博客 2168

牛皮!40张图带你看懂分布式追踪系统原理及实践,深入开发就是现在!

经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示。由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取![外链图片转存中…(img-qxp1KTuZ-1712488767364)]

2401_83916394的博客 927

【WRFDA运行第五期】运行 OBSGRID 客观分析

运行 OBSGRID 客观分析

WW、forever的博客 1049

skywalking源码解析系列二 : agent采集trace数据

在2020年3月份开始接触skywalking到现在,使用skywalking已经一年时间,期间对内部代码进行了详细阅读,并且由于项目需要,我们已经对源码进行了二开,新增了各种个性化需求,可以说,我们对skywalking底层源码了解程度已经相对较高。 本来想通过笔记对这一年来的源码阅读及理解成果进行记录,无意中发现这篇文章写得相当的好,也懒得去写了,因此直接转载,后续该系列文章会夹杂着转载与原创,欢迎各位码友交流探讨 1. 简介 本文源码解析使用的版本是 skywalking 7.0 , 不.

RIGHTSONG的博客 3524

《QGIS快速入门与应用基础》021:插件仓库 URL 获取与添加

详细介绍了在QGIS中添加第三方插件仓库的方法。首先强调必须从官方推荐、开源社区等可靠渠道获取插件仓库URL以确保安全性,并列出了4类可信获取渠道。文章分步骤讲解了URL添加流程,包括打开插件管理器设置面板、填写仓库信息、刷新缓存验证等操作。针对常见问题如URL格式错误、连接失败等提供了具体解决方案。最后总结指出,成功添加第三方仓库后即可直接搜索安装各类专业插件,从而扩展QGIS功能边界。全文注重实操指导,特别适合需要安装行业专用插件的QGIS用户参考。

LuckyHanMo的博客 466

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Spring Cloud Sleuth和skywalking-trace

spring cloud sleuth和skywalking trace均提供了请求链路追踪能力,让我们一起看看内部原理吧。

陈海龙的格物之路 1892

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

微服务链路跟踪之SkyWalking实战小结

1.关于链路跟踪 概念、原理可参考这两篇博文: 各大厂分布式链路跟踪系统架构对比 技术分析:搞懂链路追踪 2.关于SkyWalking 可参考这篇博文: skywalking 5.X 分布式链路跟踪 使用笔记 3.SkyWalking下载地址 http://skywalking.apache.org/downloads/ 4.SkyWalking服务端部署 1)将SkyW...

xianyuxiaoqiang的专栏 8923

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

基于Skywalking的全链路跟踪实现

本文重点介绍基于Skywalking的全链路实现,包括Skywalking的整体架构和基本概念原理、Skywalking环境部署、SpringBoot和Python集成Skywalking监控实现等

牧羊人的方向 2017

skywalking原理_SkyWalking的分布式跟踪系统 - 微服务监控

服务案例假设你有个订单微服务,包含以下组件MySQL数据库分表分库(2台)生产者(2台) dubbo-provider消费者 dubbo-consumer网络拓扑图如下生产者的关键代码消费者的关键代码监控启动使用 javaagent 启动生产者-javaagent:E:讯飞开发工具skywalkingagentskywalking-agent.jar -Dskywalking.agent.ser...

weixin_39793189的博客 360

Skywalking-02:如何写一个Skywalking trace插件

如何写一个Skywalking trace插件 javaagent原理 美团技术团队-Java 动态调试技术原理及实践 类图 实现 ConsumeMessageConcurrentlyInstrumentation public class ConsumeMessageConcurrentlyInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { // 需要增强的类 private static final St.

Switch的博客 749

skywalking监控mysql_基于SkyWalking的分布式跟踪系统 - 微服务监控

上一篇文章我们搭建了基于SkyWalking分布式跟踪环境,今天聊聊使用SkyWalking监控我们的微服务(DUBBO)服务案例假设你有个订单微服务,包含以下组件MySQL数据库分表分库(2台)生产者(2台) dubbo-provider消费者 dubbo-consumer网络拓扑图如下生产者的关键代码@Servicepublic class OrderServiceImpl implement...

weixin_39524247的博客 735

Windows11简单部署SkyWalking

摘要: Apache SkyWalking 是一款开源分布式系统追踪与性能监测工具,支持多语言框架(Java/.NET/Node.js等),通过代理(Agent)采集数据,提供全链路追踪、性能指标分析及日志管理。其架构包含Agent(数据采集)、OAP服务器(分析存储)、Storage(支持ES/MySQL等)和UI控制台。实现原理基于字节码注入、上下文传播(TraceID/SpanID)及数据聚合分析,帮助定位性能瓶颈。

DayDayUp的博客 200

分布式链路跟踪

文章目录方案一:自己写代码完成链路跟踪方案二:Spring Cloud Sleuth + ZipKinSleuth原理Sleuth实现Sleuth源码分析(todo)方案三:Skywalking 方案一:自己写代码完成链路跟踪 在zuul中添加过滤器: package com.cloud.mszuul.filter; import com.cloud.mszuul.Constants; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul

魏云舒的博客 5580

SkyWalking原理及实践

目录 概况 应用场景 架构分析 目录结构 部署应用 服务端 配置 部署 客户端 部署配置 本地idea配置 linux接入 使用 look Strong appearance! 概况 国产开源,Apache孵化器产品。支持非侵入式埋点,是一款基于分布式跟踪的应用程序性能监控系统。 官网:https://skywalking.apache.org/ 官方文档:https://github.com/apache/skywalking/tree/master/docs .

不积跬步无以致千里 不积小流无以成江海 2199

Java实习模拟面试之Trace体系:分布式链路追踪原理与实战解析

在微服务架构大行其道的今天,一个用户请求往往需要经过数十个甚至上百个服务的协同处理。当系统出现性能瓶颈或错误时,传统的日志排查方式如同“大海捞针”,效率极低。Trace体系(分布式链路追踪系统)应运而生,它像一张“全景地图”,清晰地描绘出请求在复杂服务网络中的完整流转路径、耗时和依赖关系。对于Java后端开发实习生而言,理解Trace体系的原理和应用,是迈向高阶开发的重要一步。本篇博客通过一场深度模拟面试。

吾为热爱计科,致力于知识分享的践行者,此博客是我在这条道路上留下的足迹。 1304
上一篇: 03-Netty编解码,粘包拆包及零拷贝详解
下一篇: 4.Skywalking原理
liuhehe321
博客等级 码龄10年 105粉丝 261原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值