参照文档
https://github.com/apache/incubator-skywalking/blob/5.x/docs/cn/Plugin-Development-Guide-CN.md#%E4%B8%89-contextsnapshot
```
当发生一次A->B的跨线程调用时:
需要在A线程中通过ContextManager#capture操作生成ContextSnapshot对象实例
将这个ContextSnapshot对象传递到B线程中
B线程通过ContextManager#continued操作完成上下文传递
```
代码如下
```java
public void beforeMethod(EnhancedInstance objInst, Method method, Object[]
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws
Throwable {
ChannelHandlerContext context = (ChannelHandlerContext) allArguments[0];
Object msg = allArguments[1];
if (msg instanceof HttpRequest) { // Client Request
System.out.println(">> " + Thread.currentThread().getId() + ":" +
context.channel().hashCode());
Attribute<ContextSnapshot> attr =
context.channel().attr(KEY_CONTEXT_SNAPSHOT);
ContextSnapshot contextSnapshot = attr.get();
attr.set(null);
if (contextSnapshot == null) {
return;
}
ContextManager.continued(contextSnapshot);
HttpRequest request = (HttpRequest) msg;
ContextCarrier contextCarrier = new ContextCarrier();
String uri = request.uri();
AbstractSpan span = ContextManager.createExitSpan(uri,
contextCarrier, String.valueOf(context.channel().remoteAddress()));
Tags.URL.set(span, request.uri());
Tags.HTTP.METHOD.set(span, request.method().name());
span.setComponent(COMPONENT_NETTY_HTTP_CLIENT);
SpanLayer.asHttp(span);
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
request.headers().set(next.getHeadKey(), next.getHeadValue());
}
context.channel().attr(KEY_CONTEXT_SNAPSHOT).set(ContextManager.capture());
System.out.println("===> encode client request $$$$$$$$ " +
Thread.currentThread().getId() + ":" + context.channel().hashCode());
}
return;
}
```
代码第45行执行时出错,错误如下:
```
ERROR 2018-09-26 17:29:56:913 InstMethodsInter : class[class
io.netty.handler.codec.http.HttpClientCodec$Encoder] before method[encode]
intercept failure-
java.lang.NullPointerException
>---at
>org.apache.skywalking.apm.agent.core.context.ContextManager.capture(ContextManager.java:143)
>---at
>org.apache.skywalking.apm.agent.core.context.ContextSnapshot.isFromCurrent(ContextSnapshot.java:119)
>---at
>org.apache.skywalking.apm.agent.core.context.ContextManager.continued(ContextManager.java:150)
>---at
>org.apache.skywalking.apm.plugin.netty.EncodeInterceptor.beforeMethod(EncodeInterceptor.java:45)
>---at
>org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:82)
>---at
>io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java)
>---at
>io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:167)
>---at
>io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:88)
>---at
>io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:348)
>---at
>io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
>---at
>io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730)
>---at
>io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:816)
>---at
>io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
>---at
>reactor.ipc.netty.channel.ChannelOperationsHandler.doWrite(ChannelOperationsHandler.java:290)
>---at
>reactor.ipc.netty.channel.ChannelOperationsHandler.drain(ChannelOperationsHandler.java:464)
>---at
>reactor.ipc.netty.channel.ChannelOperationsHandler.flush(ChannelOperationsHandler.java:192)
>---at
>io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
>---at
>io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:802)
>---at
>io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814)
>---at
>io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794)
>---at
>io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:831)
>---at
>io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1071)
>---at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
>---at
>reactor.ipc.netty.http.HttpOperations.lambda$then$0(HttpOperations.java:135)
>---at
>reactor.ipc.netty.FutureMono$DeferredFutureMono.subscribe(FutureMono.java:197)
>---at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
>---at
>reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
>---at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
>---at reactor.core.publisher.Mono.subscribe(Mono.java:3080)
>---at reactor.ipc.netty.NettyOutbound.subscribe(NettyOutbound.java:354)
>---at reactor.core.publisher.MonoSource.subscribe(MonoSource.java:51)
>---at
>reactor.ipc.netty.channel.ChannelOperations.applyHandler(ChannelOperations.java:380)
>---at
>reactor.ipc.netty.http.client.HttpClientOperations.onHandlerStart(HttpClientOperations.java:503)
>---at
>io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
>---at
>io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
>---at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
>---at
>io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
>---at java.lang.Thread.run(Thread.java:745)
```
请问该如何解决?
[ Full content available at:
https://github.com/apache/incubator-skywalking/issues/1706 ]
This message was relayed via gitbox.apache.org for [email protected]