zipkin源码 3.zipkin client brave-okhttpclient

原创
2016/11/24 21:20
阅读数 271

之前分析了sr,ss,接下来分析cr,cs 下面以okhttp client为例:

@Bean
public OkHttpClient okHttpClient(Brave brave) {
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(
                    new BraveOkHttpRequestResponseInterceptor(
                            brave.clientRequestInterceptor(),
                            brave.clientResponseInterceptor(),
                            new DefaultSpanNameProvider()))
            .build();
    return client;
}

上面代码创建了OkHttpClient,并且织入了拦截器,在真正请求执行前、后触发。

下面看BraveOkHttpRequestResponseInterceptor的intercept方法

@Override
  public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    Request.Builder builder = request.newBuilder();
    OkHttpRequest okHttpRequest = new OkHttpRequest(builder, request);
    //前置处理
    clientRequestInterceptor.handle(new HttpClientRequestAdapter(okHttpRequest, spanNameProvider));
    if(request.url()!=null&&request.url().query()!=null){
      clientTracer.submitBinaryAnnotation("params",request.url().query());
    }
    //真正的请求处理
    Response response = chain.proceed(builder.build());
    //后置处理
    clientResponseInterceptor.handle(new HttpClientResponseAdapter(new OkHttpResponse(response)));
    return response;
  }

首先看前置处理:

public class ClientRequestInterceptor {

    private final ClientTracer clientTracer;

    public ClientRequestInterceptor(ClientTracer clientTracer) {
        this.clientTracer = checkNotNull(clientTracer, "Null clientTracer");
    }

    /**
     * Handles outgoing request.
     *
     * @param adapter The adapter deals with implementation specific details.
     */
    public void handle(ClientRequestAdapter adapter) {
        //通过clientTracer创建SpanId,对应有ServerTracer
        SpanId spanId = clientTracer.startNewSpan(adapter.getSpanName());
        if (spanId == null) {
            // We will not trace this request.
            adapter.addSpanIdToRequest(null);
        } else {
            //将span信息放入header中,便于传递
            adapter.addSpanIdToRequest(spanId);
            //jiang将uri信息存入binaryAnnotation
            for (KeyValueAnnotation annotation : adapter.requestAnnotations()) {
                clientTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue());
            }
            //添加cs annotation到span
            recordClientSentAnnotations(adapter.serverAddress());
        }
    }

    private void recordClientSentAnnotations(Endpoint serverAddress) {
        if (serverAddress == null) {
            clientTracer.setClientSent();
        } else {
            clientTracer.setClientSent(serverAddress);
        }
    }
}

下面看后置处理:

public class ClientResponseInterceptor {

    private final ClientTracer clientTracer;

    public ClientResponseInterceptor(ClientTracer clientTracer) {
        this.clientTracer = checkNotNull(clientTracer, "Null clientTracer");
    }

    /**
     * Handle a client response.
     *
     * @param adapter Adapter that hides implementation details.
     */
    public void handle(ClientResponseAdapter adapter) {
        try {
            //将响应码添加到BinaryAnnotation
            for (KeyValueAnnotation annotation : adapter.responseAnnotations()) {
                clientTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue());
            }
        }
        finally
        {    
            //设置cr状态,并且提交span
            clientTracer.setClientReceived();
        }
    }
}

其实还有一种trace,那就是lc,即localTracer,它的使用方法如下:

 //生成新的span
 localTracer.startNewSpan("codec", "encode");
   try {
    //业务处理
   } finally {
     tracer.finishSpan();
   }

localTracer可以嵌入业务代码,根据自己的业务需求添加,跟踪代码块比如file io操作,业务指标比如下单次数等。

总结

1.zipkin brave基于ServerRequestInterceptor、ServerResponseInterceptor、ClientRequestInterceptor、ClientResponseInterceptor四种拦截器来处理的。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部