聊聊skywalking的async-annotation-plugin
- 2020 年 3 月 13 日
- 笔记
序
本文主要研究一下skywalking的async-annotation-plugin
AsyncExecutionInterceptorInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java
public class AsyncExecutionInterceptorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[]{ new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("doSubmit").and(takesArgumentWithType(0, "java.util.concurrent.Callable")); } @Override public String getMethodsInterceptor() { return "org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor"; } @Override public boolean isOverrideArgs() { return true; } } }; } @Override public ClassMatch enhanceClass() { return byName("org.springframework.aop.interceptor.AsyncExecutionAspectSupport"); } }
- AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法
DoSubmitMethodInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java
public class DoSubmitMethodInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { if (ContextManager.isActive()) { allArguments[0] = new SWCallable((Callable) allArguments[0], ContextManager.capture()); } } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable { return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { } }
- DoSubmitMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其beforeMethod方法将allArguments[0]包装为SWCallable
SWCallable
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java
public class SWCallable<V> implements Callable<V> { private static final String OPERATION_NAME = "SpringAsync"; private Callable<V> callable; private ContextSnapshot snapshot; SWCallable(Callable<V> callable, ContextSnapshot snapshot) { this.callable = callable; this.snapshot = snapshot; } @Override public V call() throws Exception { AbstractSpan span = ContextManager.createLocalSpan(SWCallable.OPERATION_NAME); span.setComponent(ComponentsDefine.SPRING_ASYNC); try { ContextManager.continued(snapshot); return callable.call(); } catch (Exception e) { ContextManager.activeSpan().errorOccurred().log(e); throw e; } finally { ContextManager.stopSpan(); } } }
- SWCallable实现了Callable接口,其call方法在执行callable.call()之前先ContextManager.createLocalSpan,然后执行ContextManager.continued(snapshot),之后在catch异常里头执行ContextManager.activeSpan().errorOccurred().log(e),最后在finally里头执行ContextManager.stopSpan()
小结
AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法
doc
- AsyncExecutionInterceptorInstrumentation