一文探索【skywalking】如何通过agent实现启动流程

概述

本文的主角是一款非常著名且使用的链路追踪工具:SkyWalking

SkyWalking是一个APM(application performance monitor)系统,专门为微服务、云原生和基于容器(Docker、Kubernetes、Mesos)的架构而设计,包含了云原生架构下的分布式系统的监控、跟踪、诊断功能。

通过agent的方式,可以做到对代码无侵入式的介入,实时实现整个服务链路的监控。本文的将要介绍的重点是SkyWalking如何通过agent实现如此全面的监控功能。这里提到的agent是在java中使用的agent技术,本文所讲的内容也是依托于java为基础的。

一、什么是agent?

1.1 静态agent

1.1.1 简介

JDK从1.5开始,引入了agent机制,用户可以通过-javaagent参数使用agent技术。agent技术可以使JVM在加载class文件之前先加载agent文件,通过修改JVM传入的字节码来实现自定义代码的注入。

为什么称之为静态agent?因为使用此种方式,不需要通过指定VM参数的方式,所以想要修改agent必须要对服务进行重启。

1.1.2 使用

下面我们动手实现一个简单的静态agent。

1.1.2.1 配置

实现静态agent需要配置agent的启动类,用来发现方法premain,这是实现静态agent的启动方法,因为是在jvm加载类之前,所以叫做pre-agent

静态agent通常有两种方式:

  • MANIFEST.MF 文件

    需要在resources下创建META-INF文件夹,在内部创建MANIFEST.MF文件,其格式如下(注意最后一行要换行,否则idea或报错):

    Manifest-Version: 1.0
    Premain-Class: com.wjbgn.warriors.agent.StaticAgentTest
    Can-Redefine-Classes: true
    Can-Retransform-Classes: true
    
    

    除此之外,还需要引入maven-assembly-plugin插件,否则MANIFEST.MF文件的内容会被maven打包后的内容覆盖掉。

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifestFile>
                    src/main/resources/META-INF/MANIFEST.MF
                </manifestFile>
            </archive>
        </configuration>
    </plugin>
    
    
  • 【推荐】引入编译插件 maven-assembly-plugin

    直接使用maven-assembly-plugin插件就能达到使用agent的效果,所以推荐此方式。

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifestEntries>
                    <Premain-Class>com.wjbgn.warriors.agent.StaticAgentTest</Premain-Class>
                    <Can-Redefine-Classes>true</Can-Redefine-Classes>
                    <Can-Retransform-Classes>true</Can-Retransform-Classes>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    
    

1.1.2.2 测试

  • 创建一个测试类:

    package com.wjbgn.warriors.agent;
    
    import java.lang.instrument.Instrumentation;
    
    /**
     * @description: 静态agent测试类
     * @author:weirx
     * @date:2022/6/30 15:13
     * @version:3.0
     */
    public class StaticAgentTest {
    
        /**
         * description: 静态agent启动类
         * @param agentArgs
         * @param inst
         * @return: void
         * @author: weirx
         * @time: 2022/6/30 15:14
         */
        public static void premain(String agentArgs, Instrumentation inst) {
            // 在springboot启动前打印一下文字
            System.out.println("this is static agent");
            // 打印vm参数配置的agent参数
            System.out.println(agentArgs);
        }
    }
    
    
  • 使用assembly插件打包,在idea中:

当然也可以使用命令:`mvn assembly:single`。

打包后文件在项目的`target`下。
  • 在idea添加启动参数:

蓝色部分是携带的参数,其余部分指定agent的jar包位置,完整命令如下:

```
-javaagent:E:\workspace\warriors\warriors-agent\target\warriors-agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar=[testAgnet]

```
  • 启动项目

如上所示,成功输出我们预期内容。

1.2 动态agent

1.2.1 简介

JDK在1.6版本开始,又引入了attach方式,对于运行中的应用程序,可以对其附加agent,这一操作让我们可以动态的修改已经加载的类。这也是称之为动态agent的原因。

通过VirtualMachineattach(pid)可以获得VirtualMachine实例,之后通过loadAgent(agent path)方法将指定的agent加载到正在运行的JVM当中,实现动态加载。

1.2.2 使用

1.2.2.1 配置

想要使用VirtualMachine,需要引入对应的依赖:

<dependency>
    <groupId>com.sun</groupId>
    <artifactId>tools</artifactId>
    <version>1.8</version>
    <scope>system</scope>
    <systemPath>${java.home}/../lib/tools.jar</systemPath>
</
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值