zh

skywalking java agent源码解析 skywalking git_微内核

 

 上面有两种编译方式

第一种是通过git clone源码

skywalking java agent源码解析 skywalking git_微内核_02

 

 出现上面的提示是网络原因导致下载失败,可以参考下面的解决办法解决

哔哩哔哩上面直击痛点:一招搞定GitHub开源项目下载加速! - 1.开源项目下载优化(Av94251133,P1).mp4

skywalking java agent源码解析 skywalking git_maven_03

 

 接下来我们要切换到tag 为v 8.2.0的代码

执行下面的两个命令

skywalking java agent源码解析 skywalking git_maven_04

 

 接下来我们进入到skywalking的目录执行下面的两个命令

skywalking java agent源码解析 skywalking git_java_05

 千万要注意上面的两个操作不能出现错误

skywalking java agent源码解析 skywalking git_微内核_06

 

 

 完成上面的动作之后我们就可以开始skywalking的编译了

执行编译的命令如下

第二在编译的时候一定要注意maven地址的下载,不能仅仅只配置阿里云的仓库的地址,还需要配置官方仓库的下载地址,因为有的插件在阿里云上面没有必须到官网上面去下载,这里maven的配置仓库地址如下

<!-- 阿里云仓库 -->
        <mirror>
            <id>alimaven</id>
            <mirrorOf>central</mirrorOf>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
        </mirror>
    
        <!-- 中央仓库1 -->
        <mirror>
            <id>repo1</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo1.maven.org/maven2/</url>
        </mirror>
    
        <!-- 中央仓库2 -->
        <mirror>
            <id>repo2</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo2.maven.org/maven2/</url>
        </mirror>

在编译的过程中报如下的错误

[ERROR] Failed to execute goal org.xolstice.maven.plugins:protobuf-maven-plugin:
0.6.1:compile (grpc-build) on project apm-network: protoc did not exit cleanly.
Review output for more information. -> [Help 1]

第一种网上的说法是升级maven的版本到3.6.3,我们升级了之后还是存在问题

最终的解决办法是重启电脑之后,在执行mvn命令居然成功了

 

在编译skywalking的web模块的时候,npm的仓库我们需要修改下,不能使用官网的,使用官网的整个下载会非常的缓慢

我们进入到apm-webapp模块,修改pom.xml文件,我们使用淘宝的地址

skywalking java agent源码解析 skywalking git_maven_07

 

 

skywalking java agent源码解析 skywalking git_maven_08

 

 这里即使弄成了淘宝的地址也会报错,那么如何解决了

参考这篇博客:

我们手动编译前端工程

首先我们要先安装成功npm工具

我们进入G:\skywalking-8.2.0-code-1206\skywalking-ui目录下

我们执行下面的命令,我们将npm仓库的地址设置设为

npm config set registry "http://registry.npmjs.org/"

我们不使用淘宝的镜像仓库的地址

接下来我们执行npm install命令

执行的过程中报下面的错误

PS D:\workspace\podcast-oms> npm install --registry=https://registry.npm.taobao.org
npm WARN tarball tarball data for postcss@5.2.18 (sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=) seems to be corrupted. Trying one more time.
npm ERR! path D:\workspace\podcast-oms\node_modules\.staging\postcss-8e12407f\lib\parser.js
npm ERR! code EPERM
npm ERR! errno -4048
npm ERR! syscall unlink
npm ERR! Error: EPERM: operation not permitted, unlink 'D:\workspace\podcast-oms\node_modules\.staging\postcss-8e12407f\lib\parser.js'npm ERR!  { [Error: EPERM: operation not permitted, unlink 'D:\workspace\podcast-oms\node_modules\.staging\postcss-8e12407f\lib\parser.js']
npm ERR!   cause:
npm ERR!    { Error: EPERM: operation not permitted, unlink 'D:\workspace\podcast-oms\node_modules\.staging\postcss-8e12407f\lib\parser.js'
npm ERR!      errno: -4048,
npm ERR!      code: 'EPERM',
npm ERR!      syscall: 'unlink',
npm ERR!      path:
npm ERR!       'D:\\workspace\\podcast-oms\\node_modules\\.staging\\postcss-8e12407f\\lib\\parser.js' },
npm ERR!   stack:
npm ERR!    'Error: EPERM: operation not permitted, unlink \'D:\\workspace\\podcast-oms\\node_modules\\.staging\\postcss-8e12407f\\lib\\parser.js\'',
npm ERR!   errno: -4048,
npm ERR!   code: 'EPERM',
npm ERR!   syscall: 'unlink',
npm ERR!   path:
npm ERR!    'D:\\workspace\\podcast-oms\\node_modules\\.staging\\postcss-8e12407f\\lib\\parser.js',
npm ERR!   parent: 'postcss-minify-gradients' }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).
It's possible that the file was already in use (by a text editor or antivirus)我们把
It's possible that the file was already in use (by a text editor or antivirus)

 

 使用了上面的办法还是没有解决问题,我们使用阿里的cnpm来解决

https://developer.aliyun.com/mirror/NPM?from=tnpm

我们进入到skywalking-ui

执行下面的命令

npm install -g cnpm --registry=https://registry.npm.taobao.org

skywalking java agent源码解析 skywalking git_微内核_09

 接下来要在skywalking-ui模块下执行cnpm-install命令

skywalking java agent源码解析 skywalking git_微内核_10

 

 

skywalking java agent源码解析 skywalking git_java_11

 

 

 接下来我们执行打包命令执行npm run build命令,执行成功之后打包就成功了

skywalking java agent源码解析 skywalking git_maven_12

 

skywalking java agent源码解析 skywalking git_maven_13

 

 

 会在skywalking-ui下面生成一个dist目录

skywalking java agent源码解析 skywalking git_微内核_14

 

 独立编译成的UI dist文件,也是可以放到apm-webapp中打包的,可以将上图dist中的文件拷贝到apm-webapp\target\classes\public下,然后修改apm-webapp\pom.xml,将npm install和build过程都注释了:

skywalking java agent源码解析 skywalking git_java_15

 接下来进入到skywalking源码目录执行下面的编译命令进行编译

 

mvn  clean package install -Denforcer.skip=true  -Dmaven.test.skip=true -Dcheckstyle.skip=true
就可以进行打包了,但是在打包的过程中会报错

skywalking java agent源码解析 skywalking git_微内核_16

 

 会报下面的错误

[WARNING] The assembly descriptor contains a *nix-specific root-relative-referen

因为当前是在windows环境,在binary,xml中写的确认是linux环境的路径,解决的办法就是

手动的apache-skywalking-apm-8.2.0的源码下面创建dist目录,在dist目录下面创建下面的目录,将上面编译完成的文件按照binary,xml定义的路径拷贝到下面的文件夹中

skywalking java agent源码解析 skywalking git_maven_17

 

 接下来我们要在idea中启动skywalking集群的源码

 接下来我们使用idea打开项目

 

 

然后查看设置生成的源代码(主要是看potobuf文件编译生成的源代码)

  • apm-protocol/apm-network/target/generated-sources/protobuf 选中这个目录下面的grpc-javajava,然后右键选择Mark Directory As-->Generated Sources Root如下图所示
  • oap-server/server-core/target/generated-sources/protobuf目录的grpc-java 和 java 文件夹Mark Directory As-->Generated Sources Root
  • oap-server/server-receiver-plugin/receiver-proto/target/generated-sources/protobuf 目录的grpc-java 和 java 文件夹Mark Directory As-->Generated Sources Root
  • oap-server/exporter/target/generated-sources/protobuf目录的grpc-java 和 java 文件夹Mark Directory As-->Generated Sources Root
  • oap-server/server-configuration/grpc-configuration-sync/target/generated-sources/protobuf目录的grpc-java 和 java 文件夹Mark Directory As-->Generated Sources Root
  • oap-server/oal-grammar/target/generated-sources目录的grpc-java 和 java 文件夹Mark Directory As-->Generated Sources Root
这里只需要导入上面的几个目录作为源码目录,如果多导入就会代码报错,下面我就是多导入了下面的目录结果在编译的时候代码就发生了异常,antlr4这个目录是不能被导入成源码的

 

 第二个代码的源码中包下面的错误

skywalking java agent源码解析 skywalking git_maven_18

 

 我用的idea版本是2018的版本,我安装了lombook的插件,但是本地使用的maven版本是3.6.3版本,我把maven版本更换成3.3.9版本就好了

skywalking java agent源码解析 skywalking git_maven_19

 

 

第二种是直接从apache skywalking下载的源码,直接编译

 这里我采用的是第二种直接从从apache skywalking下载的源码,直接编译

进入到skywalking源码目录执行下面的编译命令进行编译

mvn  clean package install -Denforcer.skip=true  -Dmaven.test.skip=true -Dcheckstyle.skip=true

在编译的过程中报probuffer协议编译失败,无论如何都搞不定,结果重启电脑之后,再次编译就好了、

skywalking java agent源码解析 skywalking git_微内核_20

 

 

 

skywalking java agent源码解析 skywalking git_微内核_21

 

 

 首先skywalking中存在前端

一定要保证npm 和node已经安装成功

skywalking java agent源码解析 skywalking git_java_22

 

 

 

skywalking java agent源码解析 skywalking git_maven_23

 

 

 上面保存的原因是node-8.17.0-win-x64.zip文件下载失败,我们需要手动下载node-8.17.0-win-x64.zip放在对应的maven库中,接下来在编译的时候报错

skywalking java agent源码解析 skywalking git_maven_24

 

 

skywalking java agent源码解析 skywalking git_微内核_25

 

 我们需要将npm仓库的地址换成国内的仓库地址

并且需要把 apm-webapp工程的pom文件中npm的下载地址改成国内的,不然访问在编译过程中会因为访问不了国外的仓库而报错

skywalking java agent源码解析 skywalking git_maven_26

 

 

上面的编译成功之后,我们需要将代码 导入到eclipse中

skywalking java agent源码解析 skywalking git_maven_27

 

 

 我们在eclipse中需要将编译之后的文件夹设置为源码

eclipse设置源码的方式如所示

skywalking java agent源码解析 skywalking git_maven_28

 

 

 

  • 设置 gRPC 的自动生成的代码目录,为源码目录 :
  • 将 apm-protocol/apm-network/target/generated-sources/protobuf 目录下面grpc-java 和 java 目录右键设置为 Generated Rources Root 。
  • 将 oap-server/server-core/target/generated-sources/protobuf 目录下面grpc-java 和 java目录右键设置为 Generated Rources Root 。
  • 将 oap-server/server-receiver-plugin/skywalking-istio-telemetry-receiver-plugin/target/generated-sources/protobuf目录下面grpc-java 和 java 目录右键设置为 Generated Rources Root 。

skywalking java agent源码解析 skywalking git_微内核_29

 

 

 

skywalking java agent源码解析 skywalking git_maven_30

 

 

 

skywalking java agent源码解析 skywalking git_maven_31

 

 

 

skywalking java agent源码解析 skywalking git_微内核_32

 

 

 

skywalking java agent源码解析 skywalking git_java_33

 

 

 

skywalking java agent源码解析 skywalking git_maven_34

 

 

 

skywalking java agent源码解析 skywalking git_微内核_35

 

 

IDEA 运行

skywalking的源码中存在lombok组件,我们需要安装lombok的插件

  1. 首先我们需要安装IntelliJ IDEA中的lombok插件,打开IntelliJ IDEA后点击菜单栏中的File-->Settings,或者使用快捷键Ctrl+Alt+S进入到设置页面。

  2. 我们点击设置中的Plugins进行插件的安装,在右侧选择Browse repositories...,然后在搜索页面输入lombok变可以查询到下方的Lombok Plugin,鼠标点击Lombok Plugin可在右侧看到Install按钮,点击该按钮便可安装。

skywalking java agent源码解析 skywalking git_微内核_36

skywalking java agent源码解析 skywalking git_java_37

skywalking java agent源码解析 skywalking git_java_38

  1. 我们在安装页面可以看到lombok具体支持的所有注解,在安装过程中有Downloading Plugins的提示,安装过程中进度条会变化。需要提醒的是,在安装过程中一定要保证网络连接可用且良好,否则可能会安装失败。安装成功后我们可以看到右侧的Restart按钮,此时可先不操作,因为我们还有后续的配置工作。安装完成后我们再回到Plugins,此时在右侧可以搜索到lombok,而安装前是不行的。

skywalking java agent源码解析 skywalking git_java_39

skywalking java agent源码解析 skywalking git_微内核_40

skywalking java agent源码解析 skywalking git_微内核_41

END

配置注解处理器

 

  1. 同样我们在Settings设置页面,我们点击Build,Execution,Deployment-->选择Compiler-->选中Annotation Processors,然后在右侧勾选Enable annotation processing即可。

skywalking java agent源码解析 skywalking git_maven_42

END

lombok插件的使用

 

  1. 使用前我们需要说明的是安装的插件只是一个调用,就像我们使用maven插件一样,本机需要安装maven才行。我们在使用lombok前也需要添加lombok的依赖。lombok的版本一直在更新,大家可以在百度搜索框输入lombok maven找到最新的依赖版本。
    <dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId>    <version>1.16.10</version></dependency>







  2. 2

    接下来我们编辑一个实体类Student,添加三个属性,最后在类上添加@Data属性,这个注解可以帮我们在.class文件中生成类中所有属性的get/set方法、equals、canEqual、hashCode、toString方法等。

  3. 第二

apm-agent-core是skywalking的核心类,打包会生产skywalking-agent.jar这个包

微内核架构
SkyWalking Agent 采用了微内核架构(Microkernel Architecture),那什么是微内核架构呢?微内核架构也被称为插件化架构(Plug-in Architecture),是一种面向功能进行拆分的可扩展性架构。在基于产品的应用中通常会使用微内核架构,例如,IDEA、Eclipse 这类 IDE 开发工具,内核都是非常精简的,对 Maven、Gradle 等新功能的支持都是以插件的形式增加的。

如下图所示,微内核架构分为核心系统和插件模块两大部分。

 

 

 

 

idea在编译skywalking的时候,发现项目的java源码没有编译的情况

第一要保证idea的jdk设置正确

skywalking java agent源码解析 skywalking git_java_43

 

 

项目无法编译运行的问题要设置上图保证maven正确要编译项目

 

 

 

 

 

 

 

在上图展示的微内核架构中,内核功能是比较稳定的,只负责管理插件的生命周期,不会因为系统功能的扩展而不断进行修改。功能上的扩展全部封装到插件之中,插件模块是独立存在的模块,包含特定的功能,能拓展核心系统的功能。通常,不同的插件模块互相之间独立,当然,你可以设计成一个插件依赖于另外一个插件,但应尽量让插件之间的相互依赖关系降低到最小,避免繁杂的依赖带来扩展性问题。

最终所有插件会由内核系统统一接入和管理:

首先,内核系统必须知道要加载哪些插件,一般会通过配置文件或是扫描 ClassPath 的方式(例如前文介绍的 SPI 技术)确定待加载的插件;
之后,内核系统还需要了解如何使用这些插件,微内核架构中需要定义一套插件的规范,内核系统会按照统一的方式初始化、启动这些插件;
最后,虽然插件之间完全解耦,但实际开发中总会有一些意想不到的需求会导致插件之间产生依赖或是某些底层插件被复用,此时内核需要提供一套规则,识别插件消息并能正确的在插件之间转发消息,成为插件消息的中转站。
由此可见微内核架构的好处:

测试成本下降。从软件工程的角度看,微内核架构将变化的部分和不变的部分拆分,降低了测试的成本,符合设计模式中的开放封闭原则。
稳定性。由于每个插件模块相对独立,即使其中一个插件有问题,也可以保证内核系统以及其他插件的稳定性。
可扩展性。在增加新功能或接入新业务的时候,只需要新增相应插件模块即可;在进行历史功能下线时,也只需删除相应插件模块即可。
SkyWalking Agent 就是微内核架构的一种落地方式。在前面的课时中我已经介绍了 SkyWalking 中各个模块的功能,其中 apm-agent-core 模块对应微内核架构中的内核系统,apm-sdk-plugin 模块中的各个子模块都是微内核架构中的插件模块。

SkyWalking Agent 启动流程概述
此前,在搭建 SkyWalking 源码环境的最后,我们尝试 Debug 了一下 SkyWalking Agent 的源码,其入口是 apm-agent 模块中 SkyWalkingAgent 类的 premain() 方法,其中完成了 Agent 启动的流程:

初始化配置信息。该步骤中会加载 agent.config 配置文件,其中会检测 Java Agent 参数以及环境变量是否覆盖了相应配置项。
查找并解析 skywalking-plugin.def 插件文件。
AgentClassLoader 加载插件。
PluginFinder 对插件进行分类管理。
使用 Byte Buddy 库创建 AgentBuilder。这里会根据已加载的插件动态增强目标类,插入埋点逻辑。
使用 JDK SPI 加载并启动 BootService 服务。BootService 接口的实现会在后面的课时中展开详细介绍。
添加一个 JVM 钩子,在 JVM 退出时关闭所有 BootService 服务。
SkywalkingAgent.premain() 方法的具体实现如下,其中省略了 try/catch 代码块以及异常处理逻辑:

复制代码
public static void premain(String agentArgs,
      Instrumentation instrumentation) throws PluginException {
   // 步骤1、初始化配置信息
   SnifferConfigInitializer.initialize(agentArgs);
   // 步骤2~4、查找并解析skywalking-plugin.def插件文件;
   // AgentClassLoader加载插件类并进行实例化;PluginFinder提供插件匹配的功能
   final PluginFinder pluginFinder = new PluginFinder(
      new PluginBootstrap().loadPlugins());
   // 步骤5、使用 Byte Buddy 库创建 AgentBuilder
   final ByteBuddy byteBuddy = new ByteBuddy()
      .with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS));
   new AgentBuilder.Default(byteBuddy)...installOn(instrumentation);
   // 这里省略创建 AgentBuilder的具体代码,后面展开详细说
   // 步骤6、使用 JDK SPI加载的方式并启动 BootService 服务。
   ServiceManager.INSTANCE.boot();
   // 步骤7、添加一个JVM钩子
   Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
     public void run() { ServiceManager.INSTANCE.shutdown(); }
   }, "skywalking service shutdown thread"));
}
了解了 SkyWalking Agent 启动的核心步骤之后,本课时剩余部分将对每个步骤进行深入分析。

初始化配置
在启动 demo-webapp 和 demo-provider 两个 demo 应用的时候,需要在 VM options 中指定 agent.confg 配置文件(skywalking_config 参数),agent.config 配置文件中的配置项如下:

复制代码
# 当前应用的服务名称,通过Skywalking Agent上报的Metrics、Trace数据都会
# 携带该信息进行标识
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
在  SnifferConfigInitializer.initialize() 方法中会将最终的配置信息填充到 Config 的静态字段中,填充过程如下:

将 agent.config 文件中全部配置信息填充到 Config 中相应的静态字段中。
解析系统环境变量值,覆盖 Config 中相应的静态字段。
解析 Java Agent 的参数,覆盖 Config 中相应的静态字段。
SnifferConfigInitializer.initialize() 方法的具体实现如下:

复制代码
public static void initialize(String agentOptions) {
   // 步骤1、加载 agent.config配置文件
   InputStreamReader configFileStream = loadConfig();
   Properties properties = new Properties();
   properties.load(configFileStream);
   for (String key : properties.stringPropertyNames()) {
       String value = (String)properties.get(key);
       // 按照${配置项名称:默认值}的格式解析各个配置项
       properties.put(key, PropertyPlaceholderHelper.INSTANCE
           .replacePlaceholders(value, properties));
   }
   // 填充 Config中的静态字段
   ConfigInitializer.initialize(properties, Config.class);
   // 步骤2、解析环境变量,并覆盖 Config中相应的静态字段
   overrideConfigBySystemProp();
   // 步骤3、解析 Java Agent参数,并覆盖 Config中相应的静态字段
   overrideConfigByAgentOptions(agentOptions);
   // 检测SERVICE_NAME和BACKEND_SERVICE两个配置项,若为空则抛异常(略)
   IS_INIT_COMPLETED = true; // 更新初始化标记
}
步骤 1 中的 loadConfig() 方法会优先根据环境变量(skywalking_config)指定的 agent.config 文件路径加载。若环境变量未指定 skywalking_ config 配置,则到 skywalking-agent.jar 同级的 config 目录下查找 agent.confg 配置文件。

将 agent.config 文件中的配置信息加载到 Properties 对象之后,将使用 PropertyPlaceholderHelper 对配置信息进行解析,将当前的“${配置项名称:默认值}”格式的配置值,替换成其中的默认值,demo-provider 解析结果如下图所示:

 

完成解析之后,会通过 ConfigInitializer 工具类,将配置信息填充到 Config 中的静态字段中,具体填充规则如下:

 

在接下来的 overrideConfigBySystemProp() 方法中会遍历环境变量(即 System.getProperties() 集合),如果环境变 是以 "skywalking." 开头的,则认为是 SkyWalking 的配置,同样会填充到 Config 类中,以覆盖 agent.config 中的默认值。

最后的 overrideConfigByAgentOptions() 方法解析的是 Java Agent 的参数,填充 Config 类的规则与前面两步相同,不再重复。

到此为止,SkyWalking Agent 启动所需的全部配置都已经填充到 Config 中,后续使用配置信息时直接访问 Config 中的相应静态字段即可。

 

dubbo 插件

skywalking java agent源码解析 skywalking git_maven_44

 

 

skywalking java agent源码解析 skywalking git_微内核_45

 

 

skywalking java agent源码解析 skywalking git_java_46

 

 这里要注意这里拦截点是连接类的实例方法所以继承的类是ClassInstanceMethodEnhancePluginDefine

如果是拦截类的静态方法,就要集成另外的类,如下

skywalking java agent源码解析 skywalking git_微内核_47

 

 下面的具体的拦截的实现

skywalking java agent源码解析 skywalking git_微内核_48

 

 

skywalking java agent源码解析 skywalking git_微内核_49

 

 结论

skywalking java agent源码解析 skywalking git_java_50

 

 

skywalking java agent源码解析 skywalking git_java_51

 

 

skywalking中witnessClass机制

skywalking java agent源码解析 skywalking git_微内核_52

 

 

witness机制的原理,列如dubbo有1.0  2.0两个版本

1.0中原理的拦截的MonitorFilter类对应的方法是invoke方法

2.0中原理的拦截的MonitorFilter类对应的方法变成了name方法

现在我们为dubbo1.0 编写了skywalking一个插件dubbo1.0 -jar

我们为dubbo2.0 编写了skywalking一个插件dubbo2.0 -jar

 我们如何实现dubbo1.0 -jar只拦截invoke方法

dubbo2.0 -jar只拦截name方法

这就通过witnessClass机制来实现,dubbo1.0 -jar的插件中项目组需要实现witnessClass方法,在改方法中返回一直方法,改方法只有dubbo1.0这个版本有,列如方法为aa

项目启动的时候,classload会对dububbo 1.0这个项目组运行的版本进行字节码解析看是否存在aa方法,如果aa方法与skywalking agent中witnessClass方法中定义的aa方法一致,就使用dubbo1.0 -jar只拦截invoke方法

列如sping存在多个版本

skywalking java agent源码解析 skywalking git_java_53

 

 agent后后端通信的设置

一种是是明文通信

一种是ssl通信

skywalking java agent源码解析 skywalking git_java_54

 

 

skywalking java agent源码解析 skywalking git_maven_55

 

 

skywalking java agent源码解析 skywalking git_微内核_56

 

 agent后后端的token认证

skywalking java agent源码解析 skywalking git_微内核_57

 

 grpc和后端的oap重连的时候是随机选择一个后端的oap server 实例来进行连接

 

skywalking java agent源码解析 skywalking git_maven_58

 

 应用通过grpc向opa注册注册的时候会携带当前的应用名称,注册成功之后会将当前应用的ID返回给agent,agent会存在在缓存中

skywalking java agent源码解析 skywalking git_java_59

 

 当前服务实例也需要进行注册,注册成功之后,oap会给当前的实例返回一个id,然后将这个ID缓存起来

skywalking java agent源码解析 skywalking git_maven_60

 注册成功之后,agengt需要通过定时任务不断向后端发送心跳包,说明当前的实例是存在的

skywalking java agent源码解析 skywalking git_java_61

 

skywalking java agent源码解析 skywalking git_微内核_62

 

 

skywalking java agent源码解析 skywalking git_java_63

 

 Tracesegement的核心概念

skywalking java agent源码解析 skywalking git_java_64

 

 skywalking将一个进程中的所有span封装到一个Tracesegement中

skywalking java agent源码解析 skywalking git_java_65

 

 

skywalking java agent源码解析 skywalking git_maven_66

 

 

skywalking java agent源码解析 skywalking git_maven_67

 

 

skywalking java agent源码解析 skywalking git_微内核_68

 

 

skywalking java agent源码解析 skywalking git_java_69

 

 一个Tracesement中包含多个span

span的定义如下

skywalking java agent源码解析 skywalking git_java_70

 

 span中提供了下面的方法

skywalking java agent源码解析 skywalking git_maven_71

 

 

skywalking java agent源码解析 skywalking git_java_72

 

 

skywalking java agent源码解析 skywalking git_java_73

 

 

skywalking java agent源码解析 skywalking git_微内核_74

 

 

skywalking java agent源码解析 skywalking git_maven_75

 

 

skywalking java agent源码解析 skywalking git_微内核_76

 

 

skywalking java agent源码解析 skywalking git_java_77

 

 

skywalking java agent源码解析 skywalking git_微内核_78

 

 

skywalking java agent源码解析 skywalking git_微内核_79

 

 

skywalking java agent源码解析 skywalking git_java_80

 

 

skywalking java agent源码解析 skywalking git_微内核_81

 

 

skywalking java agent源码解析 skywalking git_微内核_82

 

 

skywalking java agent源码解析 skywalking git_微内核_83

 

 

skywalking java agent源码解析 skywalking git_java_84

 

 

skywalking java agent源码解析 skywalking git_java_85

 

 

skywalking java agent源码解析 skywalking git_微内核_86

 

 

skywalking java agent源码解析 skywalking git_maven_87

 

 

skywalking java agent源码解析 skywalking git_maven_88

 

 概念3:TraceSegment中存在一个字段TraceSegmentref字段,记录了TraceSegment与TraceSegment的相互关联关系

skywalking java agent源码解析 skywalking git_java_89

 

 

skywalking java agent源码解析 skywalking git_maven_90

 

 概念4:上面的概念介绍完成之后接下来介绍context对象来实现对TraceSegment的管理和实现对span的管理

skywalking java agent源码解析 skywalking git_java_91

 

 

skywalking java agent源码解析 skywalking git_java_92

 

 

skywalking java agent源码解析 skywalking git_maven_93

 

 

skywalking java agent源码解析 skywalking git_微内核_94

 

 

skywalking java agent源码解析 skywalking git_微内核_95

 

 

skywalking java agent源码解析 skywalking git_微内核_96

 

 

skywalking java agent源码解析 skywalking git_微内核_97

 

 

skywalking java agent源码解析 skywalking git_maven_98

 

 

skywalking java agent源码解析 skywalking git_微内核_99

 

 

skywalking java agent源码解析 skywalking git_java_100

 

 

skywalking java agent源码解析 skywalking git_maven_101

 

 

skywalking java agent源码解析 skywalking git_微内核_102

 

 

skywalking java agent源码解析 skywalking git_微内核_103

 

 

skywalking java agent源码解析 skywalking git_java_104

 

 

skywalking java agent源码解析 skywalking git_微内核_105

 

 在上面创建entryspan之后,会将当前的TraceSegment上传到oap中,entryspan一般是分为两种,一个中进程传播,一种是线程传播,接下来讲讲跨进程传递,需要将Trace的信息上下文进行跨进程传播

skywalking java agent源码解析 skywalking git_java_106

 

 

skywalking java agent源码解析 skywalking git_java_107

 

 

skywalking java agent源码解析 skywalking git_微内核_108

 

 

skywalking java agent源码解析 skywalking git_微内核_109

 

 

skywalking java agent源码解析 skywalking git_java_110

 

 

skywalking java agent源码解析 skywalking git_微内核_111

 

 

skywalking java agent源码解析 skywalking git_java_112

 

 

skywalking java agent源码解析 skywalking git_微内核_113

 

 跨线程传播如下

skywalking java agent源码解析 skywalking git_java_114

 11、接下来在发送TracesSegment上报给oap的时候用到了DateCarrier组件,DateCarrier组件中会存储要发送的TracesSegment

skywalking java agent源码解析 skywalking git_java_115

 

 

skywalking java agent源码解析 skywalking git_微内核_116

 

 

skywalking java agent源码解析 skywalking git_maven_117

 

 

skywalking java agent源码解析 skywalking git_微内核_118

 

 

skywalking java agent源码解析 skywalking git_微内核_119

 

 

skywalking java agent源码解析 skywalking git_java_120

 

 

skywalking java agent源码解析 skywalking git_微内核_121

 

 

skywalking java agent源码解析 skywalking git_java_122

 

 

skywalking java agent源码解析 skywalking git_maven_123

 

 

skywalking java agent源码解析 skywalking git_java_124

 

接下来我们重点讲解下几个重要的概念

skywalking java agent源码解析 skywalking git_微内核_125

 

 

skywalking java agent源码解析 skywalking git_微内核_126

 

 

skywalking java agent源码解析 skywalking git_微内核_127

 

 我们来查看下一个案例contextManger如何进行管理的

skywalking java agent源码解析 skywalking git_微内核_128

 

 

skywalking java agent源码解析 skywalking git_maven_129

 

讲讲TraceSegment中的采样,看是否需要将当前的审判添加到TraceSegment中

skywalking java agent源码解析 skywalking git_java_130

 

 

skywalking java agent源码解析 skywalking git_微内核_131

 

 

skywalking java agent源码解析 skywalking git_微内核_132

 

 

 当TraceContext调用stopSpan关闭最后一个span的时候,会调用finish方法关闭改span所在的TraceSegment,于此同时会调用TracContext的listen通过改segment被关闭了的通知,这个时候就会将TraceSegment发送给oap的后端

skywalking java agent源码解析 skywalking git_maven_133

 

 

skywalking java agent源码解析 skywalking git_微内核_134

 

 

skywalking java agent源码解析 skywalking git_java_135

 

 TraceSegmentServiceClient主要负责将TraceSegment通过DataCarrier将TraceSegment序列化发送给后端的oap

整个序列化profuffer协议格式如下所示

skywalking java agent源码解析 skywalking git_java_136

 

 

skywalking java agent源码解析 skywalking git_微内核_137

 

 

skywalking java agent源码解析 skywalking git_微内核_138

 

 

skywalking java agent源码解析 skywalking git_java_139

 

 

skywalking java agent源码解析 skywalking git_java_140

 

 

skywalking java agent源码解析 skywalking git_maven_141

 

 

skywalking java agent源码解析 skywalking git_微内核_142

 

 这里序列化之后将segement发送给后端oap,发送的过程是阻塞性的

 

lombok