SkyWalking之agent

SkyWalking 的 agent 使用了一种称为字节码增强(bytecode instrumentation)的技术来实现代码增强、日志输出以及调用链路的获取。这种技术可以在程序运行时动态地修改类的字节码,插入特定的逻辑,例如记录方法的调用、参数和返回值等。

字节码增强技术

SkyWalking 主要利用了以下几种字节码增强技术:

  1. Java Agent
  2. Byte Buddy
  3. ASM
1. Java Agent

Java Agent 是一种允许在 JVM 启动时或运行时动态加载和修改字节码的机制。SkyWalking 使用 Java Agent 来插入其自身的字节码增强逻辑。

  • Premain 和 Agentmain 方法 :Java Agent 使用 premain 方法在 JVM 启动时执行,或者使用 agentmain 方法在 JVM 运行时动态加载。
java 复制代码
import java.lang.instrument.Instrumentation;

public class MyAgent {
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("Agent is running");
        // 可以在这里添加字节码增强逻辑
    }

    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("Agent is dynamically loaded");
        // 可以在这里添加字节码增强逻辑
    }
}
2. Byte Buddy

Byte Buddy 是一个强大的字节码操作库,SkyWalking 使用 Byte Buddy 来简化字节码操作。Byte Buddy 提供了高级的 API 来生成、修改和操作字节码。

  • 示例:通过 Byte Buddy 创建一个代理类,插入方法拦截逻辑。
java 复制代码
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;

public class MyAgent {
    public static void premain(String agentArgs, Instrumentation inst) {
        new AgentBuilder.Default()
            .type(ElementMatchers.nameContains("MyService"))
            .transform((builder, typeDescription, classLoader, javaModule) ->
                builder.visit(Advice.to(MyServiceAdvice.class).on(ElementMatchers.any()))
            ).installOn(inst);
    }
}

class MyServiceAdvice {
    @Advice.OnMethodEnter
    static void onEnter() {
        System.out.println("Before method execution");
    }

    @Advice.OnMethodExit
    static void onExit() {
        System.out.println("After method execution");
    }
}
3. ASM

ASM 是一个低级的字节码操作库,可以直接操作 JVM 字节码。SkyWalking 使用 ASM 来实现更细粒度的字节码操作。

  • 示例:使用 ASM 来修改字节码,在方法调用前后插入日志。
java 复制代码
import org.objectweb.asm.*;

public class MyClassVisitor extends ClassVisitor {
    public MyClassVisitor(ClassVisitor cv) {
        super(Opcodes.ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
        return new MyMethodVisitor(mv);
    }

    class MyMethodVisitor extends MethodVisitor {
        public MyMethodVisitor(MethodVisitor mv) {
            super(Opcodes.ASM9, mv);
        }

        @Override
        public void visitCode() {
            super.visitCode();
            mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn("Before method execution");
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        }

        @Override
        public void visitInsn(int opcode) {
            if (opcode == Opcodes.RETURN) {
                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
                mv.visitLdcInsn("After method execution");
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
            }
            super.visitInsn(opcode);
        }
    }
}

调用链路的获取

通过上述字节码增强技术,SkyWalking 在每个需要监控的方法前后插入代码,以捕获方法调用、参数、返回值和异常等信息。这些信息被用来生成分布式调用链路(Trace),并将其发送到 SkyWalking 的后端进行存储和分析。

  1. 进入方法时:记录当前时间戳、方法名、类名、参数等信息,并生成一个 Trace Segment。
  2. 方法执行完毕后:记录结束时间戳、返回值或异常信息,完成一个 Trace Segment。
  3. 分布式追踪:通过唯一的 Trace ID 和 Segment ID 将多个 Trace Segment 关联起来,形成完整的调用链路。

这些技术和方法结合使用,使得 SkyWalking 能够高效地收集和分析分布式系统的性能数据,并提供可视化的调用链路分析工具。

相关推荐
摇滚侠2 天前
Skywalking 应用性能监控和可观测性分析平台 简介
skywalking
Databuff2 天前
skywalking 快速使用入门
skywalking
摇滚侠4 天前
Apache Skywalking 实战 阅读笔记 第三章
笔记·apache·skywalking
摇滚侠5 天前
Apache Skywalking 实战 阅读笔记 第二章
笔记·apache·skywalking
Databuff5 天前
国产开源APM databuff 成为 CNCF 顶级项目opentelemetry 官宣Vendor
运维·开源·skywalking·apm·可观测性·opentelemetry
摇滚侠6 天前
Skywalking 全套教程 环境搭建 01-05
skywalking
摇滚侠6 天前
Apache Skywalking 实战 阅读笔记 第一章
笔记·apache·skywalking
就改了25 天前
Windows 环境 SkyWalking 完整实操教程
windows·微服务·skywalking
Jul1en_25 天前
【SpringCloud】SkyWalking 链路追踪知识详解及部署教程
java·后端·spring·spring cloud·skywalking
SRETalk1 个月前
SkyWalking / Jaeger / ARMS 已经有了,还需要统一可观测平台吗
skywalking·apm·jaeger·flashcat·arms