motan学习笔记 六 opentracing Brave+zipkin实现







前面我们学习了,opentracing的接口定义

本文来学习motan用filter 来拦截请求,并用brace来实现,上报数据到zipkin


zipkin是什么

本文主要讲brace 如何实现opentracing的api定义,结合motan来上传跟踪数据,并在zipkin,可以展示。

所以zipkin,就简单带过,如有朋友想了解,可以联系我,我后续写写




环境搭建zipkin


zipkin 依赖jdk1.8 所以先下载jdk   http://www.oracle.com/technetwork/indexes/downloads/index.html


接着下载 zipkin  

wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'

接着run 

nohup java -jar zipkin.jar & 


起来之后看效果



motan filter opentracing


接着来看看 motan如何搞的? 

filter+opentracing


filter 方法来拦截,之前写过motan的调用 ProtocolFilterDecorator。

 
获取trace ->  trace.buildSpan ->SpanBuilder.start-> span.log ->span.finish

/*
 * Copyright 2009-2016 Weibo, Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.weibo.api.motan.filter.opentracing;

import io.opentracing.NoopTracer;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.Tracer.SpanBuilder;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import io.opentracing.propagation.TextMapExtractAdapter;

import java.util.Iterator;
import java.util.Map.Entry;

import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.filter.Filter;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Provider;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;
import com.weibo.api.motan.util.LoggerUtil;
import com.weibo.api.motan.util.MotanFrameworkUtil;

/**
 * 
 * @Description This filter enables distributed tracing in Motan clients and servers via @see <a
 *              href="http://opentracing.io">The OpenTracing Project </a> : a set of consistent,
 *              expressive, vendor-neutral APIs for distributed tracing and context propagation.
 * @author zhanglei
 * @date Dec 8, 2016
 *
 */
@SpiMeta(name = "opentracing")
@Activation(sequence = 30)
public class OpenTracingFilter implements Filter {

    @Override
    public Response filter(Caller<?> caller, Request request) {
        Tracer tracer = getTracer();
        if (tracer == null || tracer instanceof NoopTracer) {
            return caller.call(request);
        }
        if (caller instanceof Provider) { // server end
            return processProviderTrace(tracer, caller, request);
        } else { // client end
            return processRefererTrace(tracer, caller, request);
        }
    }
    
    protected Tracer getTracer(){
        return OpenTracingContext.getTracer();
    }

    /**
     * process trace in client end
     * 
     * @param caller
     * @param request
     * @return
     */
    protected Response processRefererTrace(Tracer tracer, Caller<?> caller, Request request) {
        String operationName = buildOperationName(request);
        SpanBuilder spanBuilder = tracer.buildSpan(operationName);
        Span activeSpan = OpenTracingContext.getActiveSpan();
        if (activeSpan != null) {
            spanBuilder.asChildOf(activeSpan);
        }
        Span span = spanBuilder.start();
        span.setTag("requestId", request.getRequestId());

        attachTraceInfo(tracer, span, request);
        return process(caller, request, span);

    }

    protected Response process(Caller<?> caller, Request request, Span span) {
        Exception ex = null;
        boolean exception = true;
        try {
            Response response = caller.call(request);
            if (response.getException() != null) {
                ex = response.getException();
            } else {
                exception = false;
            }
            return response;
        } catch (RuntimeException e) {
            ex = e;
            throw e;
        } finally {
            try {
                if (exception) {
                    span.log("request fail." + (ex == null ? "unknown exception" : ex.getMessage()));
                } else {
                    span.log("request success.");
                }
                span.finish();
            } catch (Exception e) {
                LoggerUtil.error("opentracing span finish error!", e);
            }
        }
    }

    protected String buildOperationName(Request request) {
        return "Motan_" + MotanFrameworkUtil.getGroupMethodString(request);
    }

    protected void attachTraceInfo(Tracer tracer, Span span, final Request request) {
        tracer.inject(span.context(), Format.Builtin.TEXT_MAP, new TextMap() {

            @Override
            public void put(String key, String value) {
                request.setAttachment(key, value);
            }

            @Override
            public Iterator<Entry<String, String>> iterator() {
                throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.inject()");
            }
        });
    }

    /**
     * process trace in server end
     * 
     * @param caller
     * @param request
     * @return
     */
    protected Response processProviderTrace(Tracer tracer, Caller<?> caller, Request request) {
        Span span = extractTraceInfo(request, tracer);
        span.setTag("requestId", request.getRequestId());
        OpenTracingContext.setActiveSpan(span);
        return process(caller, request, span);
    }

    protected Span extractTraceInfo(Request request, Tracer tracer) {
        String operationName = buildOperationName(request);
        SpanBuilder span = tracer.buildSpan(operationName);
        try {
            SpanContext spanContext = tracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(request.getAttachments()));
            if (spanContext != null) {
                span.asChildOf(spanContext);
            }
        } catch (Exception e) {
            span.withTag("Error", "extract from request fail, error msg:" + e.getMessage());
        }
        return span.start();
    }

}

Brave 如何上报到zipkin

在motan中定义了 TracerFacoty   实现 Tracer getTracer();   方法即可


public class MyTracerFactory implements TracerFactory {
    // any tracer implementation
    final Tracer mockTracer = new MockTracer();
    
    HttpSpanCollector.Config spanConfig = HttpSpanCollector.Config.builder().compressionEnabled(false)//默认false,span在transport之前是否会被gzipped。
    		.connectTimeout(5000)//5s,默认10s
    		.flushInterval(1)//1s
    		.readTimeout(6000)//5s,默认60s
    		.build();
    final Tracer braveTracer = new BraveTracer((new Brave.Builder("service1"))
    		.spanCollector(HttpSpanCollector
    				.create("http://127.0.0.1:9411", spanConfig,new EmptySpanCollectorMetricsHandler())));

    @SuppressWarnings("deprecation")
	@Override
    public Tracer getTracer() {
//        return mockTracer;
        return braveTracer;
    }

}



然后查看 zipkin,哈哈,有数据了,需要注意的 JDK 一定要用1.8的




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Exception caught when during method invocation. request:net.risesoft.rpc.itemAdmin.DocumentManager.edit4Position(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) requestId=1771270236171928205 java.lang.reflect.InvocationTargetException: null at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.weibo.api.motan.rpc.DefaultProvider.invoke(DefaultProvider.java:64) at com.weibo.api.motan.rpc.AbstractProvider.call(AbstractProvider.java:52) at com.weibo.api.motan.transport.ProviderMessageRouter.call(ProviderMessageRouter.java:98) at com.weibo.api.motan.transport.ProviderProtectedMessageRouter.call(ProviderProtectedMessageRouter.java:75) at com.weibo.api.motan.transport.ProviderMessageRouter.handle(ProviderMessageRouter.java:93) at com.weibo.api.motan.transport.support.DefaultRpcHeartbeatFactory$HeartMessageHandleWrapper.handle(DefaultRpcHeartbeatFactory.java:98) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.processRequest(NettyChannelHandler.java:155) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.processMessage(NettyChannelHandler.java:133) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.access$000(NettyChannelHandler.java:32) at com.weibo.api.motan.transport.netty4.NettyChannelHandler$1.run(NettyChannelHandler.java:73) at java.util.concurrent.ThreadPoolExecutor.runWorker(Threa是哪里的问题
07-14

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值