zipkin dubbo mysql_dubbo + zipkin 实现全链路追踪

本文详细解析了Dubbo中TracingFilter的工作流程,该过滤器用于实现服务调用的跟踪。通过Tracer、Extractor和Injector进行上下文传播,支持客户端和服务端的请求跟踪,同时处理异步调用的情况,确保请求与响应之间的span正确完成。此外,还展示了如何处理异常并记录错误信息。
摘要由CSDN通过智能技术生成

packagebrave.dubbo.rpc;importbrave.Span;importbrave.Span.Kind;importbrave.Tracer;importbrave.Tracing;importbrave.internal.Platform;importbrave.propagation.Propagation;importbrave.propagation.TraceContext;importbrave.propagation.TraceContextOrSamplingFlags;importcom.alibaba.dubbo.common.Constants;importcom.alibaba.dubbo.common.extension.Activate;importcom.alibaba.dubbo.common.extension.ExtensionLoader;importcom.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;importcom.alibaba.dubbo.remoting.exchange.ResponseCallback;importcom.alibaba.dubbo.rpc.Filter;importcom.alibaba.dubbo.rpc.Invocation;importcom.alibaba.dubbo.rpc.Invoker;importcom.alibaba.dubbo.rpc.Result;importcom.alibaba.dubbo.rpc.RpcContext;importcom.alibaba.dubbo.rpc.RpcException;importcom.alibaba.dubbo.rpc.protocol.dubbo.FutureAdapter;importcom.alibaba.dubbo.rpc.support.RpcUtils;importjava.net.InetSocketAddress;importjava.util.Map;importjava.util.concurrent.Future;

@Activate(group= {Constants.PROVIDER, Constants.CONSUMER}, value = "tracing")// http://dubbo.io/books/dubbo-dev-book-en/impls/filter.html

//public constructor permitted to allow dubbo to instantiate this

public final class TracingFilter implementsFilter {

Tracer tracer;

TraceContext.Extractor>extractor;

TraceContext.Injector>injector;/*** {@linkExtensionLoader} supplies the tracing implementation which must be named "tracing". For

* example, if using the {@linkSpringExtensionFactory}, only a bean named "tracing" will be

* injected.*/

public voidsetTracing(Tracing tracing) {

tracer=tracing.tracer();

extractor=tracing.propagation().extractor(GETTER);

injector=tracing.propagation().injector(SETTER);

}

@Overridepublic Result invoke(Invoker> invoker, Invocation invocation) throwsRpcException {if (tracer == null) returninvoker.invoke(invocation);

RpcContext rpcContext=RpcContext.getContext();

Kind kind= rpcContext.isProviderSide() ?Kind.SERVER : Kind.CLIENT;finalSpan span;if(kind.equals(Kind.CLIENT)) {

span=tracer.nextSpan();

injector.inject(span.context(), invocation.getAttachments());

}else{

TraceContextOrSamplingFlags extracted=extractor.extract(invocation.getAttachments());

span= extracted.context() != null

?tracer.joinSpan(extracted.context())

: tracer.nextSpan(extracted);

}if (!span.isNoop()) {

span.kind(kind);

String service=invoker.getInterface().getSimpleName();

String method=RpcUtils.getMethodName(invocation);

span.name(service+ "/" +method);

parseRemoteAddress(rpcContext, span);

span.start();

}boolean isOneway = false, deferFinish = false;try (Tracer.SpanInScope scope =tracer.withSpanInScope(span)) {

Result result=invoker.invoke(invocation);if(result.hasException()) {

onError(result.getException(), span);

}

isOneway=RpcUtils.isOneway(invoker.getUrl(), invocation);

Future future = rpcContext.getFuture(); //the case on async client invocation

if (future instanceofFutureAdapter) {

deferFinish= true;

((FutureAdapter) future).getFuture().setCallback(newFinishSpanCallback(span));

}returnresult;

}catch (Error |RuntimeException e) {

onError(e, span);throwe;

}finally{if(isOneway) {

span.flush();

}else if (!deferFinish) {

span.finish();

}

}

}static voidparseRemoteAddress(RpcContext rpcContext, Span span) {

InetSocketAddress remoteAddress=rpcContext.getRemoteAddress();if (remoteAddress == null) return;

span.remoteIpAndPort(Platform.get().getHostString(remoteAddress), remoteAddress.getPort());

}static voidonError(Throwable error, Span span) {

span.error(error);if (error instanceofRpcException) {

span.tag("dubbo.error_code", Integer.toString(((RpcException) error).getCode()));

}

}static final Propagation.Getter, String> GETTER =

new Propagation.Getter, String>() {

@Overridepublic String get(Mapcarrier, String key) {returncarrier.get(key);

}

@OverridepublicString toString() {return "Map::get";

}

};static final Propagation.Setter, String> SETTER =

new Propagation.Setter, String>() {

@Overridepublic void put(Mapcarrier, String key, String value) {

carrier.put(key, value);

}

@OverridepublicString toString() {return "Map::set";

}

};static final class FinishSpanCallback implementsResponseCallback {finalSpan span;

FinishSpanCallback(Span span) {this.span =span;

}

@Overridepublic voiddone(Object response) {

span.finish();

}

@Overridepublic voidcaught(Throwable exception) {

onError(exception, span);

span.finish();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值