zipkin dubbo mysql_zipkin与dubbo整合

本文介绍了如何将Zipkin与Dubbo集成,以监控调用链并解决端口冲突、缺少client span等问题。重点在于配置TracingFilter、Dubbo Filter以及Dubbo服务的配置,以确保正确上报span到Zipkin服务器。
摘要由CSDN通过智能技术生成

2ff34e647e2e3cdfd8dca593e17d9b0a.png

利用zipkin可以对dubbo进行调用链监控,可以查到调用链中的dubbo服务的性能,并且dubbo提供了SPI的接口,能很容易完成并自定义相应的filter去监控dubbo服务。

整合

简单的描述一下,同ServletFilter一样,在dubbo中利用Filter过滤请求,传递TraceId等参数,生成相应的span传递给zipkin服务器。

引入brave-instrumentation-dubbo-rpc包,这是一个SPI的Filter包。

io.zipkin.brave

brave-instrumentation-dubbo-rpc

5.1.2

里面有一个TracingFilter的类,在其invoke方法中实现了对span的一些操作。

@Override

public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {

if (tracer == null) return invoker.invoke(invocation);

RpcContext rpcContext = RpcContext.getContext();

Kind kind = rpcContext.isProviderSide() ? Kind.SERVER : Kind.CLIENT;

final Span 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).start();

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

String method = RpcUtils.getMethodName(invocation);

span.kind(kind);

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

InetSocketAddress remoteAddress = rpcContext.getRemoteAddress();

Endpoint.Builder remoteEndpoint = Endpoint.newBuilder().port(remoteAddress.getPort());

if (!remoteEndpoint.parseIp(remoteAddress.getAddress())) {

remoteEndpoint.parseIp(remoteAddress.getHostName());

}

span.remoteEndpoint(remoteEndpoint.build());

}

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 instanceof FutureAdapter) {

deferFinish = true;

((FutureAdapter) future).getFuture().setCallback(new FinishSpanCallback(span));

}

return result;

} catch (Error | RuntimeException e) {

onError(e, span);

throw e;

} finally {

if (isOneway) {

span.flush();

} else if (!deferFinish) {

span.finish();

}

}

}

该Filter是以SPI的方式引入dubbo的,在默认文件/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter中,有这样的声明:

tracing=brave.dubbo.rpc.TracingFilter

然后在dubbo的配置中引入该Filter即可。

然后还需要为该Filter注入一个Tracing实例,并且该实例名必须为tracing。

@Configuration

public class ZipkinConfiguration {

@Autowired

private ZipkinProperties properties;

@Bean

public Tracing tracing(){

Sender sender = OkHttpSender.create(properties.getUrl());

AsyncReporter reporter = AsyncReporter.builder(sender)

.closeTimeout(properties.getConnectTimeout(), TimeUnit.MILLISECONDS)

.messageTimeout(properties.getReadTimeout(), TimeUnit.MILLISECONDS)

.build();

Tracing tracing = Tracing.newBuilder()

.localServiceName(properties.getServiceName())

.propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "shiliew"))

.sampler(Sampler.ALWAYS_SAMPLE)

.spanReporter(reporter)

.build();

return tracing;

}

}

Tracing类的主要作用是针对span的操作做一些配置,并设置上传zipkin服务器。

效果

在这里不演示如何配置dubbo服务,之前的博文有相关介绍。效果图如下:

zipkin-dubbo1.png

问题

在整合zipkin和dubbo的过程中,碰到了一些问题,在这里记录一下。

启动了两个服务提供方,使用了相同的端口号,报错

项目中有一个服务提供方moduleA,一个服务提供方和消费方moduleB。先启动了moduleA,然后启动moduleB,启动报错,显示端口已被占用。两个module的配置端口一样:

每个dubbo服务都有自己的端口,修改即可。

zipkin只记录了server span,无client span

在调用了dubbo服务之后,发现zipkin服务器上没有收到client的span,猜想问题出现在filter上面。断点调试,发现Consumer调用服务时,filter并没有执行,而Provider接收请求时有执行filter。经过排查,发现问题出现在dubbo配置上,最开始没有配置consumer方的过滤器。

添加上去即可。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值