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

motan学习笔记 一 微博轻量级RPC框架Motan

motan学习笔记 二 motan架构分析

motan学习笔记 三 motan Demo 分析

motan学习笔记 四 motan Demo 之yar 分析

motan学习笔记 五 opentracing学习入门

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

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

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


zipkin是什么

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

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


motan学习笔记 六 opentracing Brave+zipkin实现_第1张图片


motan学习笔记 六 opentracing Brave+zipkin实现_第2张图片

环境搭建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学习笔记 六 opentracing Brave+zipkin实现_第3张图片


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 The OpenTracing Project  : 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> 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的

motan学习笔记 六 opentracing Brave+zipkin实现_第4张图片


你可能感兴趣的:(motan学习笔记)