目录

skywalking源码分析

skywalking-agent源码分析

执行顺序图

该顺序图大体内容都有了,缺少最后一步的BootService的生命周期调用,即下面的接口。在这个接口中会有一些服务调用,比如向Gprc注册发送的流程*

https://openai-75050.gzc.vod.tencent-cloud.com/openaiassets_4fbd0f467d62a837ad794d6e9ba3a3fa.jpg

1
2
3
4
5
6
7
8
9
 public interface BootService {
    void prepare() throws Throwable;

    void boot() throws Throwable;

    void onComplete() throws Throwable;

    void shutdown() throws Throwable;
}

分析

分析中主要讲class Transformer implements AgentBuilder.Transformer这个实现类中的transform方法

  1. transform方法中调用pluginFinderfind方法。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
    ClassLoader classLoader, JavaModule module) {
    List<AbstractClassEnhancePluginDefine> pluginDefines = pluginFinder.find(typeDescription, classLoader);
    if (pluginDefines.size() > 0) {
        DynamicType.Builder<?> newBuilder = builder;
        EnhanceContext context = new EnhanceContext();
        for (AbstractClassEnhancePluginDefine define : pluginDefines) {
            DynamicType.Builder<?> possibleNewBuilder = define.define(typeDescription, newBuilder, classLoader, context);
            if (possibleNewBuilder != null) {
                newBuilder = possibleNewBuilder;
            }
        }
        if (context.isEnhanced()) {
            logger.debug("Finish the prepare stage for {}.", typeDescription.getName());
        }

        return newBuilder;
    }

    logger.debug("Matched class {}, but ignore by finding mechanism.", typeDescription.getTypeName());
    return builder;
}
  1. 找到所有的AbstractClassEnhancePluginDefine实现类,在迭代所有子类,调用子类的define方法。在define方法中最主要的方法是enhance。该方法是抽象方法,由子类ClassEnhancePluginDefine中调用enhanceClassenhanceInstance
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Override
protected DynamicType.Builder<?> enhance(TypeDescription typeDescription,
                                         DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader,
                                         EnhanceContext context) throws PluginException {
    newClassBuilder = this.enhanceClass(typeDescription, newClassBuilder, classLoader);

    newClassBuilder = this.enhanceInstance(typeDescription, newClassBuilder, classLoader, context);

    return newClassBuilder;
}
  1. 调用enhanceClass方法。该方法第一步也是最主要的一步调用getStaticMethodsInterceptPoints。这个方法也是抽象方法。这个方法由具体的插件实现。比如LoadBalancedConnectionProxyInstrumentation。这个类中会调用getConstructorsInterceptPoints来获取哪些方法是需要被拦截的。并且通过getMethodsInterceptor方法返回具体的实现类。这个方法类似AOP做切面处理。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private DynamicType.Builder<?> enhanceClass(TypeDescription typeDescription,
    DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader) throws PluginException {
    StaticMethodsInterceptPoint[] staticMethodsInterceptPoints = getStaticMethodsInterceptPoints();
    String enhanceOriginClassName = typeDescription.getTypeName();
    if (staticMethodsInterceptPoints == null || staticMethodsInterceptPoints.length == 0) {
        return newClassBuilder;
    }

    for (StaticMethodsInterceptPoint staticMethodsInterceptPoint : staticMethodsInterceptPoints) {
        String interceptor = staticMethodsInterceptPoint.getMethodsInterceptor();
        if (StringUtil.isEmpty(interceptor)) {
            throw new EnhanceException("no StaticMethodsAroundInterceptor define to enhance class " + enhanceOriginClassName);
        }

        if (staticMethodsInterceptPoint.isOverrideArgs()) {
            newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
                .intercept(
                    MethodDelegation.withDefaultConfiguration()
                        .withBinders(
                            Morph.Binder.install(OverrideCallable.class)
                        )
                        .to(new StaticMethodsInterWithOverrideArgs(interceptor))
                );
        } else {
            newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
                .intercept(
                    MethodDelegation.withDefaultConfiguration()
                        .to(new StaticMethodsInter(interceptor))
                );
        }

    }

    return newClassBuilder;
}

LoadBalancedConnectionProxyInstrumentation的实现方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@Override protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
    return new StaticMethodsInterceptPoint[] {
        new StaticMethodsInterceptPoint() {
            @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
                return named("createProxyInstance");
            }
            //返回具体的拦截器实现类
            @Override public String getMethodsInterceptor() {
                return METHOD_INTERCEPTOR;
            }

            @Override public boolean isOverrideArgs() {
                return false;
            }
        }
    };
}
  1. 调用enhanceInstance方法。这个方法中最主要的是调用下面的两个方法,一个是对构造器进行切面拦截,另一个是对实例对象中的方法进行拦截。比如InvocableHandlerInstrumentation这个实现类是对Springmvc中InvocableHandlerMethodinvokeForRequest进行拦截,具体的拦截器类是org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor.InvokeForRequestInterceptor
1
2
ConstructorInterceptPoint[] constructorInterceptPoints = getConstructorsInterceptPoints();
InstanceMethodsInterceptPoint[] instanceMethodsInterceptPoints = getInstanceMethodsInterceptPoints();
  1. 实现类中的方法调用,3和4步骤中对方法进行了增强即拦截进行了代理操作。以enhanceInstance为例,在调用getConstructorsInterceptPoints和方法getInstanceMethodsInterceptPoints之后,如果存在需要拦截的方法,通过返回的newClassBuilder对方法进行拦截配置。如下代码,newClassBuilder.method(junction).intercept(...)调用intercept方法,然后在intercept方法中分别调用接口的具体实现方法。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
if (existedMethodsInterceptPoints) {
    for (InstanceMethodsInterceptPoint instanceMethodsInterceptPoint : instanceMethodsInterceptPoints) {
        String interceptor = instanceMethodsInterceptPoint.getMethodsInterceptor();
        if (StringUtil.isEmpty(interceptor)) {
            throw new EnhanceException("no InstanceMethodsAroundInterceptor define to enhance class " + enhanceOriginClassName);
        }
        ElementMatcher.Junction<MethodDescription> junction = not(isStatic()).and(instanceMethodsInterceptPoint.getMethodsMatcher());
        if (instanceMethodsInterceptPoint instanceof DeclaredInstanceMethodsInterceptPoint) {
            junction = junction.and(ElementMatchers.<MethodDescription>isDeclaredBy(typeDescription));
        }
        if (instanceMethodsInterceptPoint.isOverrideArgs()) {
            newClassBuilder =
                newClassBuilder.method(junction)
                    .intercept(
                        MethodDelegation.withDefaultConfiguration()
                            .withBinders(
                                Morph.Binder.install(OverrideCallable.class)
                            )
                            .to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader))
                    );
        } else {
            newClassBuilder =
                newClassBuilder.method(junction)
                    .intercept(
                        MethodDelegation.withDefaultConfiguration()
                            .to(new InstMethodsInter(interceptor, classLoader))
                    );
        }
    }
}

总结重要实现及接口

该流程过程中主要是在enhance方法内进程代理(拦截器)的创建。具体的拦截器接口有InstanceConstructorInterceptor,InstanceMethodsAroundInterceptor,StaticMethodsAroundInterceptor,然后在上面三个接口的子类中有些会实现EnhancedInstance接口进行动态属性添加。而最主要的三个接口的实现类的调用是通过newClassBuilder.method(junction).intercept方法内部调用的。

如下图:

https://openai-75050.gzc.vod.tencent-cloud.com/openaiassets_25ae358016d07d16f7b21a43244f69fb.jpg

https://openai-75050.gzc.vod.tencent-cloud.com/openaiassets_1bc32d15b4d5356579290127b3becfa9.jpg

https://openai-75050.gzc.vod.tencent-cloud.com/openaiassets_d1c141b9b567a289045dee4badc758e2.jpg