链路图
树形图
列表
插件集成步骤:
1.插件定义
实例方法定义:ClassInstanceMethodsEnhancePluginDefine
静态方法定义:ClassStaticMethodsEnhancePluginDefine
- 定义要拦截的目标类------全类名匹配,注解匹配,子类匹配等
- 定义要增强的构造器
- 定义要拦截的目标方法------方法名称+参数个数等方式匹配
- 指定增强的拦截类------全类名
2.插件拦截器
类似于环绕通知,在方法执行之前,之后,出现异常做一些处理
- 实例方法拦截:InstanceMethodsAroundInterceptor
/**
* EnhancedInstance:每个目标类都会实现这个接口,目的是增加一个属性可以传递的数据------跨线程?
**/
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result){
}
- 静态方法拦截:StaticMethodsAroundInterceptor
3.配置插件定义类
skywalking-plugin.def,key-value结构
key:自定义名称
value:插件定义类全类名
例子:netty-server=org.apache.skywalking.apm.plugin.netty.server.define.HttpObjectEncoderInstrumentation
问题及风险:
1.链路跨线程
-
使用注解
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>${skywalking.version}</version>
</dependency>
@TraceCrossThread
public static class MyCallable<String> implements Callable<String> {
@Override
public String call() throws Exception {
return null;
}
}
...
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(new MyCallable());
-
引入提供的插件
参考下面两篇博客
- 对于内部类和lambda表达式框架不支持增强的解决方法
-
如果可以改源代码可以使用这种方式
- 如果不可以改源码
可以在目标方法和入参内部类之间加一层,在这一层里面存储上一个Segment的信息,在调用时将上一个Segment和现在的Segment串起来
具体参考kafka-plugin实现
2.链路跨进程
kafka生产、消费是两个进程,以这两个为例说明大概流程
kafka生产者
kafka消费者